2014-11-14 96 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