VB.NET 2012, ADO.NET, SQL Server 2014
I setup a parameterized query that works well. I essentially read records from a DataTable
that comes from a different source than my SQL Server. It's small enough that I elected to read record by record and build a query and hit the SQL Server for a match.
However I am having trouble getting a match when one of my fields is supposed to be matched for a null. I know a record exist because I can look at it in SQL Server directly and see it. With my parameterized query somehow the null is being translated improperly. I tried manually replacing the parameter @EngSerialNo
with DBNull.Value
and still doesn't work. Almost seems like I need two different queries depending if my DataTable
value is null.
sqQry.AppendLine("SELECT CityCode,CarNum,RegNum,Event,EngSerialNum)")
sqQry.AppendLine("FROM [MyDB].[dbo].[Events]")
sqQry.AppendLine("WHERE (CityCode=@City AND CarNum=@CarNo AND RegNum=@RegNo AND Event=@Event AND EngSerialNum=@EngSerialNo)") 'this looks for a value in EngSerialNo
'sqQry.AppendLine("WHERE (CityCode=@City AND CarNum=@CarNo AND RegNum=@RegNo AND Event=@Event 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
Update: I ended up creating a dynamic SQL for every DataRow. Basically for each DataRow I check key fields for NULL or an actual value and create the appropriate SQL command text. I have 4 fields that could contain a NULL but for sake of simplicity I only demonstrated one here. I think the developer can follow the example to create their own query.
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 (CityCode=@City AND CarNum=@CarNo AND RegNum=@RegNo AND Event=@Event AND EngSerialNum IS NULL)") 'this looks for a Null in EngSerialNo
Else
sqQry.AppendLine("WHERE (CityCode=@City AND CarNum=@CarNo AND RegNum=@RegNo AND Event=@Event AND EngSerialNum=@EngSerialNo)") 'this looks for a value in EngSerialNo
End If
Return sqQry.ToString
End Function