VBA/SQL 参数化查询 - 字段列表中的未知列

Posted

技术标签:

【中文标题】VBA/SQL 参数化查询 - 字段列表中的未知列【英文标题】:VBA/SQL Parameterized Query - Unknown Column in Field List 【发布时间】:2021-08-30 16:08:54 【问题描述】:

我正在使用 mysql ODBC 5.1 驱动程序在 Excel 中的 VBA 中工作,并且在尝试使用参数化 SQL 查询将行插入表中时遇到问题。在参数化之前,查询运行良好,但我遇到了 SQL 注入问题,其中一列中有包含 SQL 代码的 cmets,并将插入全部搞砸了。我现在正在转向参数化的最佳实践,但我似乎无法找出我在下面的代码中做错了什么以及为什么它给了我“'字段列表'中的“未知列'p1'”错误。

For y = 0 To 20000
        qry = "INSERT INTO ticket_system.ticket_weekly_snapshot (issue_type,key_name,summary,assignee,reporter,priority,status,resolution,created,updated,due_date,project,linked_issues,parent_link,epic_link,parent_undefined,label,comment) VALUES ("
        Dim adoCmd As Object
        Dim adoRS As Object
        Set adoCmd = CreateObject("ADODB.Command")
        With adoCmd
            .ActiveConnection = cnn
            .CommandType = adCmdText
            If alltix.Range("A2").Offset(y, 0) = "" Then
                Exit For
            End If
            For x = 0 To 17
                Dim l As Integer
                l = Len(alltix.Range("A2").Offset(y, x))
                If l = 0 Then
                    l = 10
                End If
                .Parameters.Append .CreateParameter("p" & x + 1, adLongVarChar, adParamInput, l, alltix.Range("A2").Offset(y, x))
                If x = 17 Then
                    qry = qry & "p" & x + 1 & ")"
                Else
                    qry = qry & "p" & x + 1 & ","
                End If
            Next x
        End With
        adoCmd.CommandText = qry
        Set adoRS = adoCmd.Execute

我目前有一个用于测试的消息框提示,显示查询正在正确构建,以“VALUES (p1, p2, ... p18)”结尾,这就是我看到的几乎所有参数化查询的工作方式至今。所有参数都正确添加到 adoCmd,没有值错误或类似的东西。 adoCmd 执行时,最后一行出现“字段列表中的未知列”错误。谁能帮助我并告诉我哪里出错了?

【问题讨论】:

你能添加你的表的定义吗?可能是vba不能管理像database.table这样的完全限定名,只能管理表名。在 ODBC 定义中选择默认数据库。 我确实在我的 ODBC 定义中选择了我的数据库。我只是尝试将其从查询文本中取出,而只使用“ticket_weekly_snapshot”,但这并没有解决它。我认为问题必须在参数本身的某个地方,因为在我切换到使用参数之前,我运行查询很好(即我的数据集的前 2 行插入没有问题)。 【参考方案1】:

动态构建参数名称对我有用,但可以尝试未命名参数的选项。在循环外声明 l 变量。真的应该在程序顶部声明所有变量。

qry = "INSERT INTO ticket_system.ticket_weekly_snapshot " & _
      "(issue_type,key_name,summary,assignee,reporter,priority,status,resolution,created,updated,due_date,project,linked_issues,parent_link,epic_link,parent_undefined,label,comment) " & _
      "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
...
Dim l As Integer
For x = 0 To 17
    l = Len(alltix.Range("A2").Offset(y, x))
    If l = 0 Then
        l = 10
    End If
    .Parameters.Append .CreateParameter(, adLongVarChar, adParamInput, l, alltix.Range("A2").Offset(y, x))
Next

更多信息请查看How do I use parameters in VBA in the different contexts in Microsoft Access?

【讨论】:

感谢您的建议。循环中定义的“l”变量是我提出的另一个问题的快速补丁,即您不能在不分配参数长度的情况下为参数分配类型,但不能分配长度为 0。我确实读过在您的链接中“ADO 不支持命名参数。虽然您可以传递名称,但它不会被处理。”我刚刚尝试了未命名的参数,现在得到了一个不同的错误:“对象'_Command'的方法'执行'失败。”也与之前的错误同时发生。知道是什么原因造成的吗? 我在最近的评论中摆脱了“执行”错误,不使用 ADODB 记录集来执行命令,而只是调用 adoCmd.Execute。但是,在调用 Execute 函数时,我的 Excel 实例完全崩溃了。根本没有错误消息,不会运行到命令超时长度,只是在 5 到 10 秒内完全崩溃。初步研究表明这可能是驱动程序问题,但是我尝试使用已安装的其他驱动程序并遇到相同的崩溃。任何想法为什么会发生这种情况? 不知道。无法复制错误,因此无法建议解决方案。但是,我正在使用 Access db 进行测试,而不是 MySQL。 我想不通,我所做的任何更改都没有影响任何东西。谢天谢地,我知道对传入信息的限制,所以我觉得只使用字符串查询并从连接中执行它就比较舒服。我已经将 Chr*34) 和 Chr(39) 替换为 Chr(96) (即将 ' 和 " 更改为到目前为止它工作正常。感谢您帮助理解它!

以上是关于VBA/SQL 参数化查询 - 字段列表中的未知列的主要内容,如果未能解决你的问题,请参考以下文章

#1054 - '字段列表'中的未知列 'id' - phpMyAdmin

“字段列表”中的未知列“PROGRAMMEDescription”

字段列表中的未知列续集

VBA SQL'没有为一个或多个必需参数提供值'但字段存在

ER_BAD_FIELD_ERROR:“字段列表”中的未知列

“字段列表”中的未知列名“table.column”