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

时间:2015-08-20 14:14:45

标签: c# .net 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
}

服务器是Microsoft SQL Server实例。

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

从我的阅读,以及像这样的测试代码,做我在这里做的事情不能正常工作,因为显然你不能用这种方式进行“等于空”的比较 - 你应该这样做“一片空白”。

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

该文章建议您可以使用OR运算符执行WHERE Field1 = 25 OR Field1 IS NULL之类的操作。问题是,通过单次调用此函数,我想检查 null并且只检查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;
}

// ...

这真的是它需要做的吗?有没有更有效的方法来执行此操作而不重复if块并使用参数而不是将查询字符串连接在一起?

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

6 个答案:

答案 0 :(得分:2)

为什么不使用:

string theQuery = "SELECT Field1, Field2, Field3 FROM MyTable WHERE ISNULL(Field1,'') = @F1";

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

答案 1 :(得分:1)

SQL Server有一个名为ISNULL(Column,Value)的函数,您可以在其中指定一列来检查并设置默认值,以防此列为NULL。 您可以查看here

答案 2 :(得分:0)

如果你想避免使用阻止,你可以将查询改为这样的东西:

SELECT Field1,Field2,Field3 FROM MyTable 
WHERE COALESCE(Field1,'') = @F1 AND COALESCE(Field2,-1) = @F2

答案 3 :(得分:0)

您可以执行类似

的操作
WHERE ISNULL(Field, '') = @F1

在这种情况下,NULL字段被视为空字符串。另一种方式是:

WHERE Field IS NULL OR Field = @1

答案 4 :(得分:0)

处理NULL的方式是正确的方法。也许你可以使用像这样的辅助方法:

private string AppendParameter(string query, string parameterName, string parameterValue, SqlParameterCollection parameters)
{
     if (string.IsNullOrEmpty(parameterValue))
         query += "Field1 IS NULL ";
     else
     {
         query += "Field1 = " + parameterName + " ";
         parameters.AddWithValue(parameterName, parameterValue);
     }

     return query;
}

答案 5 :(得分:0)

SqlCommand myCommand = new SqlCommand(@"SELECT Field1,Field2,Field3 
     FROM MyTable 
     WHERE 
     ( (@F1 IS NULL AND [field1] IS NULL) OR [field1] = @F1 ) AND
     ( (@F2 IS NULL AND [field2] IS NULL) OR [field2] = @F2 );", this.myconn);
    myCommand.Parameters.Add("@F1", System.Data.SqlDbType.VarChar).Value = DBNull.Value;
    myCommand.Parameters.Add("@F2", System.Data.SqlDbType.Int).Value = DBNull.Value;


    if (!string.IsNullOrEmpty(f1))
      myCommand.Parameters["@F1"].Value = f1;
    if (f2 != -1)
      myCommand.Parameters["@F2"].Value = f2;

这将使用字段上的索引。