ADODB插入字符串中的单引号

时间:2018-09-21 18:49:01

标签: sql sql-server excel-vba

我正在使用Excel工作表从SQL Server获取信息,然后有人添加了一些信息,然后将其重新插入到其他SQL数据库和表中。我遇到的问题是字符串中包含',因此INSERT INTO失败

Private Sub SaveData_Click()
Dim conn As New ADODB.Connection
Dim iRowNo, answer, secondOne As Integer
Dim sJobNum, sWorkOrderNum, sItemDesc, sType, sCatName As String

answer = MsgBox("Are you sure you want to save the sheet?", vbYesNo + vbQuestion, "Save Categories")

If answer = vbYes Then
    With Sheets("JobInformation")

        'Open a connection to SQL Server
        conn.Open "Provider=SQLOLEDB;Data Source=10.0.2.2;Initial Catalog=ReportingAddOn;User ID=SOMEID;Password=SOMEPASSWORD"

        'Skip the header row
        iRowNo = 2

        'Loop until empty cell in CustomerId
        Do Until .Cells(iRowNo, 1) = ""
            If .Cells(iRowNo, 5) <> "" Then
               sJobNum = .Cells(iRowNo, 1)
               sWorkOrderNum = .Cells(iRowNo, 2)
               sItemDesc = .Cells(iRowNo, 3)
               sType = .Cells(iRowNo, 4)
               sCatName = .Cells(iRowNo, 5)

               'Generate and execute sql statement to import the excel rows to SQL Server table
               conn.Execute "INSERT INTO dbo.TryOutCategoryComplete (JobNumber, WorkOrderNumber, ItemDescription, Type, CategoryName) VALUES ('" & sJobNum & "', '" & sWorkOrderNum & "', '" & sItemDesc & "', '" & sType & "', '" & sCatName & "')"
            End If
            iRowNo = iRowNo + 1
        Loop

        secondOne = MsgBox("Categories Saved!", vbOKOnly, "Successfully Saved!")

        conn.Close
        Set conn = Nothing

        Sheets("CategoryName").Select
    End With
End If
End Sub

sItemDesc具有以下内容时,问题就出现了:

It is a value that hasn't happened

因此“没有”会出错,因为其中的单引号引起了INSERT INTO

中字符串的结尾

那么我该如何继续使用INSERT的原样,但要注意单引号块呢?

1 个答案:

答案 0 :(得分:1)

一个经典示例,说明为什么在将值插入应用程序层的后端数据库时应使用parameterization(行业最佳实践)的原因,因为不需要引号括起来,因此不会影响实际值。

Excel VBA可以使用ADO Command对象运行参数化查询,您可以在其中将参数绑定到准备好的语句,以使SQL与VBA值分离。在下面,您将看到循环外一次分配的准备好的SQL语句:

Dim conn As New ADODB.Connection
Dim cmd As ADODB.Command
Dim strSQL As String
...

With Sheets("JobInformation")

    'Open a connection to SQL Server
    conn.Open "Provider=SQLOLEDB;Data Source=10.0.2.2;Initial Catalog=ReportingAddOn;User ID=SOMEID;Password=SOMEPASSWORD"

    'Skip the header row
    iRowNo = 2

    ' PREPARED STATEMENT WITH QMARK PLACEHOLDERS
    strSQL = "INSERT INTO dbo.TryOutCategoryComplete (JobNumber, WorkOrderNumber, ItemDescription, Type, CategoryName) VALUES (?, ?, ?, ?, ?)"

    'Loop until empty cell in CustomerId
    Do Until .Cells(iRowNo, 1) = ""
        If .Cells(iRowNo, 5) <> "" Then
           sJobNum = .Cells(iRowNo, 1)
           sWorkOrderNum = .Cells(iRowNo, 2)
           sItemDesc = .Cells(iRowNo, 3)
           sType = .Cells(iRowNo, 4)
           sCatName = .Cells(iRowNo, 5)

          ' COMMAND OBJECT 
           Set cmd = New ADODB.Command

           With cmd
               .ActiveConnection = cn    ' CONNECTION OBJECT
               .CommandText = strSQL     ' SQL STRING     
               .CommandType = adCmdText

               ' BINDING PARAMETERS
               .Parameters.Append .CreateParameter("sJobNumParam", adVarChar, adParamInput, , sJobNum)
               .Parameters.Append .CreateParameter("sWorkOrderNumParam", adVarChar, adParamInput, , sWorkOrderNum)
               .Parameters.Append .CreateParameter("sItemDescParam", adVarChar, adParamInput, , sItemDesc)
               .Parameters.Append .CreateParameter("sTypeParam", adVarChar, adParamInput, , sType)
               .Parameters.Append .CreateParameter("sCatNameParam", adVarChar, adParamInput, , sCatName)

               .Execute                 ' RUN ACTION
           End With

           Set cmd = Nothing

        End If
        iRowNo = iRowNo + 1
    Loop

    secondOne = MsgBox("Categories Saved!", vbOKOnly, "Successfully Saved!")

    conn.Close
    Set conn = Nothing

    Sheets("CategoryName").Select
End With