2014-11-14 87 views
0

VB.NET 2012,ADO.NET,SQL Server 2014带有WHERE子句的SQL Server参数化查询,空值为

我设置了一个很好的参数化查询。我基本上从DataTable读取来自与我的SQL Server不同的来源的记录。它足够小,我选择按记录读取记录并构建一个查询并击中SQL Server进行匹配。

但是,当我的某个字段应该与null匹配时,我无法获得匹配。我知道存在一条记录,因为我可以直接在SQL Server中查看它并查看它。用我的参数化查询以某种方式,null被错误地翻译。我尝试用DBNull.Value手动替换参数@EngSerialNo,但仍然无法正常工作。几乎看起来像我需要两个不同的查询,具体取决于我的DataTable值是否为空。

sqQry.AppendLine("SELECT CityCode,CarNum,RegNum,Event,EngSerialNum)") 
sqQry.AppendLine("FROM [MyDB].[dbo].[Events]") 
sqQry.AppendLine("WHERE ([email protected] AND [email protected] AND [email protected] AND [email protected] AND [email protected])") 'this looks for a value in EngSerialNo 
'sqQry.AppendLine("WHERE ([email protected] AND [email protected] AND [email protected] AND [email protected] AND EngSerialNum IS NULL)")  'this looks for a Null in EngSerialNo  

Dim cmd As New SqlCommand 

With cmd 
     .Connection = connMyDb 
     .CommandType = CommandType.Text 
     .CommandText = sqQry.ToString 

     'cycle through each DataRow in the DataTable and check for returns 
     Dim total As Integer = 0 
     For Each row As DataRow In dtMain.Rows 
      .Parameters.Clear() 
      .Parameters.AddWithValue("@City", row.Item("City")) 
      .Parameters.AddWithValue("@CarNo", row.Item("CarNo")) 
      .Parameters.AddWithValue("@RegNo", row.Item("RegNo")) 
      .Parameters.AddWithValue("@Event", row.Item("Event")) 
      .Parameters.AddWithValue("@EngSerialNo", row.Item("EngSerialNo")) 'how do I get this to look for a null value when the DataTable contains a null value? 

      Dim rowsAffected As Integer = .ExecuteNonQuery() 
      total += rowsAffected 
     Next row 
End With 

更新:我最终为每个DataRow创建了一个动态SQL。基本上对于每个DataRow,我检查NULL或实际值的关键字段并创建适当的SQL命令文本。我有4个字段可以包含NULL,但为了简单起见,我只在这里演示了一个。我认为开发人员可以按照该示例创建自己的查询。

Dim cmd As New SqlCommand 
With cmd 
     .Connection = connMyDb 
     .CommandType = CommandType.Text 

     'cycle through each DataRow in the DataTable and check for returns 
     Dim total As Integer = 0 
     For Each row As DataRow In dtMain.Rows 
      .CommandText = BuildSql(row) 

      .Parameters.Clear() 
      .Parameters.AddWithValue("@City", row.Item("City")) 
      .Parameters.AddWithValue("@CarNo", row.Item("CarNo")) 
      .Parameters.AddWithValue("@RegNo", row.Item("RegNo")) 
      .Parameters.AddWithValue("@Event", row.Item("Event")) 
      .Parameters.AddWithValue("@EngSerialNo", row.Item("EngSerialNo")) 

      Dim rowsAffected As Integer = .ExecuteNonQuery() 
      total += rowsAffected 
     Next row 
End With 

Private Function BuildSql(ByVal dr As DataRow) As String 
    Dim sqQry As New StringBuilder 
    sqQry.AppendLine("SELECT CityCode,CarNum,RegNum,Event,EngSerialNum)") 
    sqQry.AppendLine("FROM [MyDB].[dbo].[Events]") 

    If dr.Item("EngSerialNo") Is DBNull.Value Then 
     sqQry.AppendLine("WHERE ([email protected] AND [email protected] AND [email protected] AND [email protected] AND EngSerialNum IS NULL)")  'this looks for a Null in EngSerialNo    
    Else 
     sqQry.AppendLine("WHERE ([email protected] AND [email protected] AND [email protected] AND [email protected] AND [email protected])") 'this looks for a value in EngSerialNo 
    End If 

    Return sqQry.ToString 
End Function 

回答

3

在SQL你不能比较空值,即EngSerialNum = null始终计算为假,即使在字段中的值是零。

要么你可以动态地创建查询,让您使用is null匹配空值,或者您可以使用这样的表达式:

((EngSerialNum is null and @EngSerialNo is null) or EngSerialNum = @EngSerialNo) 
+0

嗯,我做了一些研究,并指出,在设置ANSI_NULLS数据库本身作为一个选项会做我所需要的。 http://msdn.microsoft.com/en-us/library/ms188048.aspx试过了,它没有工作。我会提出你的建议。我实际上有两个领域,我需要检查这么幸运,我不必写一个巨大的替代查询。 – sinDizzy 2014-11-15 23:34:06

+0

@sinDizzy:你可以使用'set ansi_nulls off'来比较空值。但是,这种可能性将在未来消除。参考:http://msdn.microsoft.com/en-us/library/ms188048.aspx – Guffa 2014-11-16 01:49:49

+0

啊是的,我明白你的意思了。所以将实现我的查询不依赖于该设置。换句话说,使用IS NULL。我会发布一次,我有一个工程。 – sinDizzy 2014-11-16 02:39:57