Вставка ADODB с одинарной кавычкой в ​​строке - PullRequest
0 голосов
/ 21 сентября 2018

Я использую лист 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 голосов
/ 21 сентября 2018

Классический пример того, почему следует использовать параметризацию (лучшая отраслевая практика) при вставке значений в внутренние базы данных на прикладном уровне, так как вложения в кавычки не нужны и, следовательно, не влияют на фактические значения.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...