如何将这些作为Null而不是Nothing写入我的数据库

时间:2010-01-12 21:26:22

标签: sql vb.net .net-1.1

如何更改以下代码以写入数据库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

干杯,

麦克

6 个答案:

答案 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)”;

然后使用command.Parameters.Add

将命名参数添加到命令中

对于要存储为NULL的值,请将参数值设置为DBNull.Value。

答案 3 :(得分:0)

答案 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)

对于一个简单的问题,这可能看起来有很多变化,但是您的代码将更安全,可读和可维护。