2

我收到此错误:“输入字符串的格式不正确。”

这是我的代码:

    private void UpdatePOdetailBalance(int Qty)
    {
        int newbal;

        SqlCommand com = new SqlCommand();

        com.Connection = cn;

        newbal = Convert.ToInt16(txtQtyOrdered.Text) - Qty;
        com.CommandText =
            "UPDATE PODetail SET BalanceQty="+ newbal +" WHERE OrderID=" +
             Convert.ToInt16(txtPONumber.Text) + "AND ItemID=" +
             Convert.ToInt16(txtItemNo.Text);


        com.ExecuteNonQuery();

    }

    private void btnOK_Click(object sender, EventArgs e)
    {

            UpdatePOdetailBalance(Convert.ToInt16(txtQuantity.Text));

    }

我想计算等于 txtQtyOrdered 减去 Qty 的 newbal,但我遇到了这个错误,请帮我解决这个问题。谢谢。

4

7 回答 7

6

您的错误消息所述的问题可能是尝试将文本框中的值转换为短整数的行之一。如果不进行任何检查,您的用户输入的值可能不是数字,并且您会收到此错误消息(例如,如果您的用户将文本框留空)。

在尝试执行查询之前,您应该尝试检查文本框内容是否可以使用TryParse转换为有效的短整数

int ordered;
if(!int16.TryParse(txtQtyOrdered.Text, out ordered))
{
    MessageBox.Show("Invalid number for Ordered quantity");
    return;
}
int orderID;
if(!int16.TryParse(txtPONumber.Text, out orderID))
{
    MessageBox.Show("Invalid number for OrderId");
    return;
}
int itemID;
if(!int16.TryParse(txtItemNo.Text, out itemID))
{
    MessageBox.Show("Invalid number for ItemID");
    return;
}

此时,您可以使用转换后的短整数执行计算,然后以这种方式编写查询(在 AND 之前添加一个空格)

  com.CommandText =
        "UPDATE PODetail SET BalanceQty="+ newbal.ToString() +
        " WHERE OrderID=" + orderID.ToString() + 
        " AND ItemID=" + itemID.ToString();

但是从不建议将查询文本和用户输入的字符串连接作为一种好的做法(在您的情况下是无害的,因为如果转换成功,您不必担心 Sql Injection,但不要养成这样做的习惯)。
所以编写这个查询的完美方式是使用参数化查询

  com.CommandText =
        "UPDATE PODetail SET BalanceQty=@newbal " +
        " WHERE OrderID=@orderID " + 
        " AND ItemID= @itemID"

  com.Parameters.AddWithValue("@newbal", newBal);
  com.Parameters.AddWithValue("@orderID", orderID);
  com.Parameters.AddWithValue("@itemID", itemID);
  com.ExecuteNonQuery();

作为一篇关于参数化查询以及为什么使用它们的好文章,我建议阅读Jeff Atwood的这些旧词

于 2013-10-12T15:08:09.070 回答
2

我建议根据以下代码审查建议进行更改(按价值顺序列出(“修复”的成本/收益)):

  1. 这种访问数据库的方法不应该通过读取控件来获取其值。相反,应该有一个事件处理程序,例如按钮单击,它使用 TryParse 解析其他控件的值,正如 gregjer 回答的那样。通过分离 UI 和数据代码,数据访问层更容易测试,并且通过在表面(UI 层)解析处理错误用户输入的异常将尽快捕获。
  2. 通过数据库中的字符串或带有 .NET 的数据访问层中的动态 SQL 对 SQL 注入是开放的。您正在通过解析文本来解决该问题,您做得真棒。但是,这已经由 .NET 团队通过提供参数化命令来处理。请参阅 MSDN SqlCommand.Parameters 或在此处查看简要说明,包括消费开发人员如何理解此主题:添加 SqlCommand 参数时何时应使用“SqlDbType”和“size”?
  3. 变量命名。代替 Qty,标准 .NET 命名约定将要求数量,camelCased,因为它是一个参数和完整的人类语言名称,而不是速记或缩写,尤其是对于公开​​可见的位。IntelliSense 使长变量名不成问题。由于 .NET 仅使用记事本很笨拙,因此应该假定其他开发人员正在使用诸如 VisualStudio 或 SharpDevelop 之类的 IDE,因此请使用有意义的名称。
  4. 应该使用存储过程。每次执行此 SQL 时,SQL Server 都需要最低限度地检查其命令缓存,但如果命令已从缓存中刷新,则需要对 SQL 命令进行解释和缓存(放入缓存)。这以及使用存储过程需要在每次调用数据库时“传送”更少字节的事实。
于 2013-10-12T15:32:37.440 回答
1

您需要在“AND”之前放置一个空格,并且您正在尝试将字符串转换为不是整数的整数。

于 2013-10-12T15:05:44.210 回答
0

我认为你需要调试你的代码。在调试期间从“com.CommandText”复制您的查询并粘贴到 SQL Server 中,您会发现错误

只有一个查询错误没有别的...可能是txtQtyOrdered值不是整数,也需要空格“AND ItemID=”到“AND ItemID=”

谢谢,

塔哈

于 2013-10-12T15:30:18.630 回答
0

该错误意味着您尝试转换的字符串不是整数。尝试使用 int.TryParse

int newbal;

if(int.TryParse(txtQtyOrdered.Text, out newbal))
    newbal = newbal - Qty;

与您尝试转换的其他文本相同

...并在 " AND 之前添加空格,这将产生下一个错误

于 2013-10-12T15:06:53.457 回答
0

首先 -您在“AND”之前缺少一个空格

  1. 您应该尝试在更新语句之前解析值。
  2. 如果文本框的输入格式不正确,您应该决定要做什么,而不是在尝试更新时出现异常。
  3. 这不是格式化字符串的正确方法,您应该使用string.Format
于 2013-10-12T15:24:19.550 回答
0

当您有多个参数并且使用OracleDB2数据库时,有时可能会遇到此问题。他们不支持命名参数或者它没有打开。

甲骨文:

    Dim cmd As OracleCommand = DirectCast(connection.CreateCommand, OracleCommand)
    cmd.BindByName = True

确保您的参数以与 sql 语句相同的顺序添加到命令对象

于 2019-03-08T20:26:18.743 回答