如何更改以下代码以写入数据库null而不是空字符串?
Public Sub SetChangeRequest(ByVal referenceLeaseID As Integer, _
ByVal referenceCustomerID As Integer, _
Optional ByVal custUnitNum As Object = Nothing, _
Optional ByVal driverFirstName As Object = Nothing, _
Optional ByVal driverLastName As Object = Nothing, _
Optional ByVal driverEmail As Object = Nothing, _
Optional ByVal plateNumber As Object = Nothing, _
Optional ByVal plateProvince As Object = Nothing, _
Optional ByVal usageProvince As Object = Nothing, _
Optional ByVal invoiceGroups As Object = Nothing)
mcmd = New SqlCommand
mcmd.CommandType = CommandType.Text
mcmd.Connection = mcn
mcmd.CommandText = "IF EXISTS (SELECT * FROM ChangeRequest WHERE ReferenceLeaseID = " & referenceLeaseID & ")" & vbNewLine & _
"DELETE FROM ChangeRequest WHERE ReferenceLeaseID = " & referenceLeaseID & vbNewLine & _
"INSERT INTO ChangeRequest (ReferenceLeaseID, ReferenceCustomerID, CustomerUnitNum, DriverFirstName, DriverLastName, DriverEmail, PlateNumber, PlateProvince, UsageProvince, InvGroupID)" & vbNewLine & _
"VALUES ('" & referenceLeaseID & "', '" & referenceCustomerID & "', '" & custUnitNum & "', '" & driverFirstName & "', '" & driverLastName & "', '" & driverEmail & "', '" & plateNumber & "', '" & plateProvince & "', '" & usageProvince & "', '" & invoiceGroups & "')"
mcn.Open()
mcmd.ExecuteScalar()
mcn.Close()
End Sub
干杯,
麦克
答案 0 :(得分:6)
他们构建查询的方式效率低,难以阅读,容易出错,而且最糟糕的是SQL注入攻击。您应该使用SQL参数:
mcmd.CommandText = "IF EXISTS (SELECT * FROM ChangeRequest WHERE ReferenceLeaseID = @referenceLeaseID") " _
"DELETE FROM ChangeRequest WHERE ReferenceLeaseID = @referenceLeaseID " & _
"INSERT INTO ChangeRequest (ReferenceLeaseID, ReferenceCustomerID, CustomerUnitNum, DriverFirstName, DriverLastName, DriverEmail, PlateNumber, PlateProvince, UsageProvince, InvGroupID) " & _
"VALUES (@referenceLeaseID, @referenceCustomerID, @custUnitNum, @driverFirstName, @driverLastName, @driverEmail, @plateNumber, @plateProvince, @usageProvince, @invoiceGroups)"
您可以为以下参数指定值:
mcmd.Parameters.Add("@parameterName", If(ParameterValue Is Nothing, DBNull.Value, ParameterValue))
答案 1 :(得分:1)
有一个名为DBNull.Value
的东西。这就是你想要的而不是Nothing
。
要测试数据库值是否为NULL
,请使用函数IsDBNull
。
答案 2 :(得分:1)
我建议最大的事情是你使用参数化的sql语句,因为你自己开放sql注入。
e.g。 command.CommandText =“INSERT SomeTable(SomeField)VALUES(@SomeField)”;
将命名参数添加到命令中对于要存储为NULL的值,请将参数值设置为DBNull.Value。
答案 3 :(得分:0)
您可以使用DBNull.Value。 http://msdn.microsoft.com/en-us/library/system.dbnull.value.aspx
答案 4 :(得分:0)
使用参数化查询,而不是将值放在SQL中。除了修复空值问题外,它还可以防止SQL注入。
Public Sub SetChangeRequest(ByVal referenceLeaseID As Integer, _
ByVal referenceCustomerID As Integer, _
Optional ByVal custUnitNum As Object = Nothing, _
Optional ByVal driverFirstName As Object = Nothing, _
Optional ByVal driverLastName As Object = Nothing, _
Optional ByVal driverEmail As Object = Nothing, _
Optional ByVal plateNumber As Object = Nothing, _
Optional ByVal plateProvince As Object = Nothing, _
Optional ByVal usageProvince As Object = Nothing, _
Optional ByVal invoiceGroups As Object = Nothing)
mcmd = New SqlCommand
mcmd.CommandType = CommandType.Text
mcmd.Connection = mcn
mcmd.CommandText = "IF EXISTS (SELECT * FROM ChangeRequest WHERE ReferenceLeaseID = " & referenceLeaseID & ")" & vbNewLine & _
"DELETE FROM ChangeRequest WHERE ReferenceLeaseID = " & referenceLeaseID & vbNewLine & _
"INSERT INTO ChangeRequest (ReferenceLeaseID, ReferenceCustomerID, CustomerUnitNum, DriverFirstName, DriverLastName, DriverEmail, PlateNumber, PlateProvince, UsageProvince, InvGroupID)" & vbNewLine & _
"VALUES (@ReferenceLeaseID, @ReferenceCustomerID, @CustomerUnitNum, @DriverFirstName, @DriverLastName, @DriverEmail, @PlateNumber, @PlateProvince, @UsageProvince, @InvGroupID)"
mcmd.Parameters.AddWithValue("ReferenceLeaseID", referenceLeaseID)
mcmd.Parameters.AddWithValue("ReferenceCustomerID", referenceCustomerID )
mcmd.Parameters.AddWithValue("CustomerUnitNum", custUnitNum)
mcmd.Parameters.AddWithValue("DriverFirstName", driverFirstName)
mcmd.Parameters.AddWithValue("DriverLastName", driverLastName)
mcmd.Parameters.AddWithValue("DriverEmail", driverEmail)
mcmd.Parameters.AddWithValue("PlateNumber", plateNumber)
mcmd.Parameters.AddWithValue("PlateProvince", plateProvince)
mcmd.Parameters.AddWithValue("UsageProvince", usageProvince)
mcmd.Parameters.AddWithValue("InvGroupID", invoiceGroups)
mcn.Open()
mcmd.ExecuteScalar()
mcn.Close()
End Sub
答案 5 :(得分:0)
如果您确实 想要,您可以通过执行以下操作来构建您正在构建的查询:
"VALUES (" & IIf(referenceLeaseID Is Nothing, "NULL", "'" & referenceLeaseID & "'"))
...但请请不要这样做。代码很难看,难以维护,并且允许SQL注入等各种不愉快。
相反,使用参数化查询 - 整个过程很好地解释了in this MSDN article。
第一遍后,您的代码将如下所示:
Dim cmd = New SqlCommand(".... VALUES (@p0)")
cmd.Parameters.Add(New SqlParameter("@p0", referenceLeaseID))
...它仍然不漂亮:长多行SQL查询将继续使代码混乱。
要解决此问题,请将查询移至存储过程中。这具有巨大的优势,能够在用于此目的的编辑器中编写SQL,而不是在代码中编写它。如果您使用最新版本的SQL Server Studio,或者当然是必不可少的SQL Prompt utility,您甚至可以获得一些不错的Intellisense支持。
存储过程与您当前的查询几乎完全相同,还有一些额外的参数声明:
CREATE PROCEDURE UpdateDriverRecord
@referenceLeaseID NVARCHAR(42)
BEGIN
...VALUES(referenceLeaseID = @referenceLeaseID)
END
您的最终代码如下所示:
Dim cmd = New SqlCommand("UpdateDriverRecord")
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add("@referenceLeaseID", SqlDbType.NVarChar, 42)
对于一个简单的问题,这可能看起来有很多变化,但是您的代码将更安全,可读和可维护。