2014-11-14 1 views
0

VB.NET 2012, ADO.NET, SQL Server 2014null이있는 WHERE 절이있는 SQL Server 매개 변수가있는 쿼리

잘 작동하는 매개 변수가있는 쿼리를 설정했습니다. 본질적으로 필자는 SQL 서버가 아닌 다른 소스에서 가져온 DataTable의 레코드를 읽었습니다. 그것은 내가 레코드로 레코드를 읽고 쿼리를 작성하고 SQL Server에 일치하도록하기에 충분할만큼 작습니다.

그러나 내 필드 중 하나가 null과 일치해야하는 경우 일치하는 데 문제가 있습니다. SQL Server에서 직접보고 볼 수 있기 때문에 레코드가 있다는 것을 알고 있습니다. 어떻게 든 매개 변수화 된 쿼리를 사용하면 null이 부적절하게 변환됩니다. 수동으로 매개 변수 @EngSerialNoDBNull.Value으로 바꾸려고 시도했지만 여전히 작동하지 않습니다. 내 DataTable 값이 null인지에 따라 두 가지 다른 쿼리가 필요하다.

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 명령 텍스트를 만듭니다. NULL을 포함 할 수있는 4 개의 필드가 있지만 단순성을 위해 여기서만 보여줍니다. 개발자가 예제를 따라 자신의 쿼리를 만들 수 있다고 생각합니다.

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에서는 null 값을 비교할 수 없습니다, 즉 EngSerialNum = null은 항상 필드의 값이 null 인 경우에도 false로 평가합니다.

어느 쪽이든 당신은 널 (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

+0

@sinDizzy : 널 값을 비교할 수 있으려면'set ansi_nulls off'를 사용하십시오. 그러나 그 가능성은 앞으로 제거 될 것입니다. Ref : http://msdn.microsoft.com/en-us/library/ms188048.aspx – Guffa

+0

아, 네가 지금 무슨 뜻인지 안다. 그래서 그 설정에 의존하지 않는 내 쿼리를 구현합니다. 즉, IS NULL을 사용하십시오. 나는 일하는 것이 있으면 게시 할 것입니다. – sinDizzy

관련 문제