ASP .NET C#SQL在ExecuteScalar上返回DBNULL

use*_*873 1 c# sql-server asp.net

好的我已经创建了一个产品表[ID,itemCode],一个销售表和一个返回库存物品的SUM的视图.事情是,如果该物品尚未售出,则视图中没有该物品的记录.我需要检查物品是否有库存才能完成进一步的销售等.

我做的是这样的:

    string selectSQL = "SELECT [total] FROM [stock] WHERE ([itemCode] = " + TextBoxCode.Text + ")";
    SqlConnection con = new SqlConnection(connectionString);
    SqlCommand com = new SqlCommand(selectSQL, con);
    try
    {
        con.Open();          
        object obj = com.ExecuteScalar();

        if (obj == null) //(also tried is DBNull)
        {
            lblStatus.Text = "Does not exist in stock";
        }
        else
        {
            sum = com.ExecuteScalar().ToString();
            lblStatus.Text = "Items in stock: " + sum;
        }
    }
    catch (Exception err)
    {
        lblStatus.Text = err.Message;
    }
    finally
    {
        con.Close();
    }
Run Code Online (Sandbox Code Playgroud)

当物品实际存在于库存中时它工作正常但如果没有记录我得到错误:

将nvarchar值'1E001'转换为数据类型int时转换失败.

'1E001'是我库存视图中的第一个itemCode,但它与我尝试插入的itemCode无关.

问题似乎在于:

object obj = com.ExecuteScalar(); 
Run Code Online (Sandbox Code Playgroud)

我也试过了

"SELECT COUNT(total) FROM [stock] WHERE ([itemCode] = " + TextBoxCode.Text + ")";
Run Code Online (Sandbox Code Playgroud)

结果相同.我无法让它发挥作用.

jfo*_*las 8

如果ItemCode不是数字,那么您需要在插入TextBoxCode.Text的代码之前和之后包含单引号.例:

string selectSQL = "SELECT [total] FROM [stock] WHERE ([itemCode] = '" + TextBoxCode.Text + "')";
Run Code Online (Sandbox Code Playgroud)

警告:使用此代码可以让您全面了解SQL注入攻击!

使用参数的首选方法是:

string selectSQL = "SELECT [total] FROM [stock] WHERE ([itemCode] = @ItemCode)";
SqlCommand com = new SqlCommand(selectSQL, con);
com.Parameters.AddWithValue("@ItemCode", TextBoxCode.Text);
Run Code Online (Sandbox Code Playgroud)

对于您的问题本身,如果结果集中没有行,则ExecuteScalar的结果将为null(.NET null条件).这与结果集的第一行的第一个字段是数据库空值(DBNull.Value)不同.

要检查两者,请使用:

if (obj == null || obj == DBNull.Value) 
Run Code Online (Sandbox Code Playgroud)

注意:您不应该第二次执行ExecuteScalar(如果它不是null),因为您已经在obj变量中得到了结果.