sql-server - 如何从 VBA ADODB 中的参数化 SQL Server 查询中诊断语法错误
问题描述
我正在使用 VBA adodbINSERT
根据 Excel 行内容在 SQL Server 中编写语句。
我正在使用参数化查询,因此我的 VBA 代码具有以下形式:
sqlStatement = "INSERT INTO dbo.mytable (" & Join(insertElement(0), ", ") & ") VALUES (" & Join(insertElement(2), ", ") & ")"
Set cm = New ADODB.Command
With cm
Debug.Print (sqlStatement)
.ActiveConnection = conn
.CommandText = sqlStatement
.CommandType = adCmdText
For Each e In insertElement(1)
Set Pm = .CreateParameter(, adVarChar, 3, 1024, e)
.Parameters.Append Pm
Next e
Set rs = .Execute
End With
其中insertElement(0)
是字段名称数组, ...(1) 是值数组, ...(2) 是?
用于支持参数化的占位符数组
当我运行此代码时,出现错误
[Microsoft][ODBC Driver 13 for SQL Server][SQL Server]“输出”附近的语法不正确
但是,当我询问sqlStatement
文本时,声明中的任何地方都没有“输出”。文本格式如下:
INSERT INTO dbo.mytable ([my_field_1],[my_field_2],[somefieldshaveweirdcharslike+#], ...) VALUES (?, ?, ?, ...)
因此,如果我没有直接提供“输出”命令,并且由于它正在服务器端处理,我无法直接看到该语句,我该如何诊断语法?
解决方案
您应该能够通过迭代您的数组并以您认为合适的任何方式连接您的值来简单地构建您的 SQL 语句,而不是尝试将一堆参数插入一堆问号。像这样的东西(我假设它insertElement
实际上是一个二维数组而不是一个集合;如果它真的是一个集合,那么你需要做类似的事情For Each
):
sqlStatement = "INSERT INTO dbo.mytable (" & Join(insertElement(0), ", ") & ") VALUES ("
Set cm = New ADODB.Command
With cm
.ActiveConnection = conn
.CommandType = adCmdText
Dim aCount As Integer
aCount = Ubound(insertElement(1))
For i = 0 To aCount - 1
sqlStatement = sqlStatement & "'" & insertElement(1,i) & "'" & _
Iif(i <> aCount - 1, ",", "")
Next
.CommandText = sqlStatement
Set rs = .Execute
End With
综上所述,如果您想更深入地了解错误发生的位置,您可以尝试迭代Connection
对象的Errors 集合。Err
由于尝试使用连接可能会产生多个错误,因此仅使用对象进行故障排除可能有点困难。
最后,最好INSERT
在服务器端的存储过程中设置语句,并以这种方式将值作为参数传递,除非您没有理由担心注入攻击。
推荐阅读
- java - 无法引用封闭范围中定义的非最终局部变量显示
- javascript - Debounced 函数在 VueJS 中永远不会触发
- rust - 匹配背后的魔力:`&std::option::Option 没有实现
== std::option::Option<_> - jq - 如果外部数组的名称 == 'something',则将值添加到 JSON 数组
- react-native - 如何在 React 导航 5 堆栈导航器中按下后退按钮导航到屏幕
- excel - VBA:设置一个等于过滤条件的数组
- excel - Excel-如何返回每个单元格具有不同变体的嵌套 ISBLANK IF 语句?
- ios - 在 iOS14 上释放 wkwebview 时,发送手势事件导致崩溃
- python - 为什么我的窗口不适用于 on_draw?
- firebase - 在firebase存储触发器中获取userId