【问题标题】:C# error : Input string was not in a correct formatC# 错误:输入字符串的格式不正确
【发布时间】:2013-10-12 15:01:52
【问题描述】:

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

这是我的代码:

    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,但我收到此错误,请帮助我。谢谢。

【问题讨论】:

  • 请在您的命令周围使用 using-blocks 并学习使用绑定参数。在短期内,打印你的 sql 字符串,你在正确的地方缺少一个空白。

标签: c# sql visual-studio format


【解决方案1】:

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

在尝试执行查询之前,您应该尝试检查文本框内容是否可以使用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 的read these old words

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 他的代码与动态SQL无关(另外一个原因是SQL注入开放)
    【解决方案3】:

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

    【讨论】:

    • 就这样?说说这里使用的不良做法怎么样?
    • 是的,有不好的做法,但他显然是一个正在学习的年轻程序员,所以与其通过指出不好的做法来破坏某人,为什么不帮助他解决他的迫切需求,然后他可以学习好的方面/不好的做法。
    • 没有。在这种情况下,一行不是正确的答案。你可以指出不好的做法而不会让别人失望!
    • @Yosi 同意,您可以帮助人们学习而不会破坏他们。我的回答是在为家人做早餐时快速回答。在此线程上还有其他经过深思熟虑的深入答案。谢谢你们的cmets。将来我会更加深思熟虑地回答问题。
    • 对不起,如果我太苛刻了。这是昨天在 meta 中提出的一个问题,与此讨论有关-meta.stackexchange.com/questions/200420/…
    【解决方案4】:

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

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

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

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

    【讨论】:

      【解决方案5】:

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

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

      谢谢,

      塔哈

      【讨论】:

        【解决方案6】:

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

        1. 您应该尝试在更新语句之前解析值。
        2. 您应该决定在文本框输入的格式不正确的情况下要做什么,而不是在尝试更新时遇到异常。
        3. 这不是格式化字符串的正确方法,您应该使用string.Format

        【讨论】:

        • 你是对的,string.format 比字符串连接更好,但是在处理查询语句和使用命令对象时,使用参数总是更好。
        【解决方案7】:

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

        甲骨文:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多