Не могу избавиться от надоедливых синтаксических ошибок - PullRequest
0 голосов
/ 05 июля 2018

Так что я немного новичок в кодировании SQL, и в моей компании уже существует система заказов на покупку, запустив лист с макросами .xlsx.

Я получаю «Неверный синтаксис рядом», «и когда я меняю случайную запятую здесь или там, я получаю различные ошибки. Когда он выдает ошибки и я выполняю горячую отладку, он выделяет SetRS = Conn.Execute(SQL) линия

Так что-нибудь выделяется для всех лучше обученных глаз? Спасибо!

Dim Report As Worksheet
Set Report = Excel.ActiveSheet
SQL = "insert into Purchases.dbo.POs values(" & Range("H12").Value & "," & Range("H30").Value & Excel.WorksheetFunction.Sum(Report.Range("F16:F29")) & "," & Range("A34").Value & _
"','" & Range("F7").Value & "','" & Range("C12").Value & "','" & Range("A38").Value & "',0,'" & Code & "')"
'MsgBox SQL
Set RS = Conn.Execute(SQL)

Ответы [ 2 ]

0 голосов
/ 05 июля 2018

StringBuilders имеют функцию AppendFormat, которая упрощает создание операторов SQL.

Метод StringBuilder.AppendFormat

Добавляет строку, возвращенную обработкой строки составного формата, которая содержит ноль или более элементов формата, к этому экземпляру. Каждый элемент формата заменяется строковым представлением соответствующего аргумента объекта.

Примечание. VBA использует StringBuilder.AppendFormat_4 для обработки строки формата и массива значений.

StringBuilder.AppendFormat_4 Format, Array()
Const Code = 10
Dim sb As Object
Dim SQL As String
Dim Report As Worksheet
Set Report = Excel.ActiveSheet

Set sb = CreateObject("System.Text.StringBuilder")
SQL = "INSERT INTO Purchases.DBO.Pos VALUES({0},'{1}',{2},'{3}','{4}','{5}','{6}',0,'{7}')"
sb.AppendFormat_4 SQL, Array(Range("H12").Value, _
                           Range("H30").Value, _
                           Excel.WorksheetFunction.Sum(Range("F16:F29")), _
                           Range("A34").Value, _
                           Range("F7").Value, _
                           Range("C12").Value, _
                           Range("A38").Value, _
                           Code)

SQL = sb.ToString

ИМО. использование заглавных букв SQL упрощает чтение оператора SQL. Я также хотел бы добавить список полей для заявления.

INSERT INTO Purchases.DBO.Pos(FirstName,LastName) VALUES('Tin','Man')
0 голосов
/ 05 июля 2018

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

Тем не менее я на 95% уверен, что Range("H30").Value & Excel.WorksheetFunction.Sum(Report.Range("F16:F29")) - это не то, что вы намеревались делать.

Разбить его:

Dim value1 As Double
value1 = ActiveSheet.Range("H12").Value

Dim value2 As String
value2 = "'" & ActiveSheet.Range("H30").Value & "'"

Dim value3 As Double
value3 = Excel.WorksheetFunction.Sum(Report.Range("F16:F29"))

Dim value4 As Double
value4 = ActiveSheet.Range("A34").Value

Dim value5 As String
value5 = "'" & ActiveSheet.Range("F7").Value & "'"

Dim value6 As String
value6 = "'" & ActiveSheet.Range("C12").Value & "'"

Dim value7 As String
value7 = "'" & ActiveSheet.Range("A38").Value & "'"

Dim value8 As Long
value8 = 0

Dim value9 As String
value9 = "'" & Code & "'"

Теперь вы можете проверить каждое значение индивидуально. Все хорошо? Теперь объедините их:

Dim values As Variant
values = Join(Array(value1, value2, value3, value4, value5, value6, value7, value8, value9), ",")

Dim sql As String
sql = "insert into Purchases.dbo.POs values(" & values & ")"

Строка SQL выглядит правильно?

Debug.Print sql
Stop 'hit Ctrl+G to bring up the *immediate pane* and view the output

Если вы возьмете этот вывод и запустите его в SSMS, работает ли вставка? Да уж? Тогда ты в порядке!

conn.Execute sql

Теперь, скажем, ActiveSheet.Range("H30").Value содержит вредоносную строку; выполнение его непосредственно из соединения приведет к сбою оператора insert, и SQL Server с радостью выполнит исполняемый оператор SQL, который был небрежно присоединен к запросу: это приходит на ум , lookup " SQL-инъекция "для получения дополнительной информации.

Узнайте, как вы можете использовать ADODB.Command с ADODB.Parameter для каждого значения и немедленно избежать этой уязвимости безопасности. Он также защищает ваш код от создания недопустимого оператора SQL, когда значение содержит, скажем, ' одинарную кавычку - и в качестве бонуса вам больше не нужно заботиться об окружающих строках одинарными кавычками, сервер будет обрабатывать их.

...