.NET:如何处理 SQL 查询中可能出现的空值?

fdm*_*ion 6 .net c# sql-server

代码:

private void DoSomethingWithDatabase(string f1, int f2) 
{
    SqlCommand myCommand = new SqlCommand("SELECT Field1,Field2,Field3 FROM MyTable WHERE Field1 = @F1 AND Field2 = @F2", this.myConn);
    myCommand.Parameters.Add("@F1", System.Data.SqlDbType.VarChar);
    myCommand.Parameters.Add("@F2", System.Data.SqlDbType.Int);

    if (f1 == "") 
        myCommand.Parameters["@F1"].Value = DBNull.Value;
    else
        myCommand.Parameters["@F1"].Value = f1;

    if (f2 < 0)
        myCommand.Parameters["@F2"].Value = DBNull.Value;
    else
        myCommand.Parameters["@F2"].Value = f2;

    // code to do stuff with the results here
}
Run Code Online (Sandbox Code Playgroud)

服务器是 Microsoft SQL Server 实例。

数据库表MyTable包含可为空的字段。因此 null 是执行查询时要搜索的有效值。

从我的阅读以及像这样的测试代码来看,像我在这里所做的那样做的事情不能正常工作,因为显然你不能以这种方式进行“等于空”比较 - 你应该做“IS NULL” .

看起来您可以通过将 ANSI_NULL 设置为 OFF(根据https://msdn.microsoft.com/en-us/library/ms188048.aspx)来纠正此问题并使其工作,但它也表明此方法已弃用,不应使用。

那篇文章建议您可以使用 OR 运算符来执行类似WHERE Field1 = 25 OR Field1 IS NULL. 问题是,与这种功能的单呼,我想检查或者无效,只有空,或者对于给定的恒定值,而不是其他。

到目前为止,似乎我基本上需要逐个、逐个字符串地构建查询,以考虑 NULL 值的可能性。所以我需要做类似的事情:

string theQuery = "SELECT Field1,Field2,Field3 FROM MyTable WHERE ";
if (f1 == "")
    theQuery += "Field1 IS NULL ";
else
    theQuery += "Field1 = @F1 ";

// ...

SqlCommand myCommand = new SqlCommand(theQuery, this.myConn);
if (f1 == "")
{
    myCommand.Parameters.Add("@F1", System.Data.SqlDbType.VarChar);
    myCommand.Parameters["@F1"].Value = f1;
}

// ...
Run Code Online (Sandbox Code Playgroud)

真的需要这样做吗?有没有更有效的方法来做到这一点而不重复该if块并使用参数而不是将查询字符串连接在一起?

(注意:示例中的空字符串在此处转换为 NULL。在我实际使用的场景中,从不使用空字符串,而是存储 NULL。数据库不受我控制,所以我不能t 只是说“将所有 NULL 更改为空字符串”。对于 int 也是如此-如果我们传递-1给函数,例如,它应该测试空值。不好的做法?也许,但数据库本身不在我的控制,只有访问它的代码。)

Kab*_*lak 3

为什么不使用:

string theQuery = "SELECT Field1, Field2, Field3 FROM MyTable WHERE ISNULL(Field1,'') = @F1";
Run Code Online (Sandbox Code Playgroud)

这样您就可以摆脱 if 块,并且您的 null 值将被解释为空字符串,就像您的f1变量一样。

  • @Kabulan0lak 现在它可以工作了,但是 Andy Nichols 的评论是正确的,如果列有一个索引,在过滤器上使用 ISNULL 会阻止使用索引。 (2认同)