【问题标题】:INSERT INTO Too few parametersINSERT INTO 参数太少
【发布时间】:2018-12-12 02:03:21
【问题描述】:

我有一个名为 tb_tools 的表,其中包含以下字段:

  • TOOL_ID(短文本)[key_field]
  • 描述(短文本)
  • 机架(短文本)
  • 列(编号)
  • 评论(长文本)

在名为 frm_insertion 的表单中,我有一个带有点击事件的按钮

Private Sub btn_add_Click()
    Dim part_temp As String
    Dim tempNum As Integer
    Dim tempStr As String

    tempNum = 12
    tempStr = "test"

    tool_temp = Nz(DLookup("[TOOL_ID]", "tb_tools", "[TOOL_ID]='" & [box_dien] & "'"), "-1")

    If StrComp(tool_temp, "-1", vbTextCompare) = 0 Then
        CurrentDb.Execute "INSERT INTO [tb_dies] ([TOOL_ID], [DESCRIPTION], [RACK], [COLUMN], [COMMENTS]) " _
            & "VALUES (" & tool_temp & "," & tempStr & "," & tempStr & "," & tempNum & "," & tempStr & ")"
    End If
End Sub

我在 INSERT INTO 行中收到错误“参数太少。应为 1”。我检查了字段名称。事实上,我是直接从表格中复制粘贴到代码中的。

我还使用了此处提供的代码: http://forums.devarticles.com/microsoft-access-development-49/check-if-a-field-exists-in-a-table-using-vba-58559.html 检查字段是否可用

【问题讨论】:

  • 将你的 SQL 字符串构建成一个字符串,然后执行currentdb.execute(ssql)。这样你就可以在执行它之前debug.print SQLmsgbox(sSQL)。我的猜测是您的变量值之一是空白,或者有需要处理的特殊字符。通过显示代码生成的 SQL,我们可以回到问题所在。考虑一下您的值是否看起来像...。似乎您的字符串值周围没有撇号,这也会导致问题。考虑使用参数化查询来避免头痛并避免 SQL 注入问题。

标签: sql vba ms-access


【解决方案1】:

在查询中使用参数时,这可能更容易理解。

Private Sub btn_add_Click()

    Dim qdf As DAO.QueryDef

    Set qdf = CurrentDb.CreateQueryDef("", _
        "PARAMETERS lToolID LONG, DescText TEXT (255), RackText TEXT (255), " & _
        "ColumnNum LONG, CommentText LONGTEXT; " & _
        "INSERT INTO tb_dies (TOOL_ID, DESCRIPTION, RACK, COLUMN, COMMENTS) " & _
        "VALUES (lToolID, DescText, RackText, ColumnNum, CommentText)")

    With qdf
        .Parameters("lToolID") = 1
        .Parameters("DescText") = "Some Text"
        .Parameters("RackText") = "Some Rack Text"
        .Parameters("ColumnNum") = 5
        .Parameters("CommentText") = "Some really long comments"
        .Execute
    End With

    Set qdf = Nothing

End Sub  

SQL 读作:

PARAMETERS  lToolID LONG
            , DescText TEXT (255)
            , RackText TEXT (255)
            , ColumnNum LONG
            , CommentText LONGTEXT; 
INSERT INTO tb_dies (TOOL_ID, DESCRIPTION, RACK, COLUMN, COMMENTS) 
VALUES      (lToolID, DescText, RackText, ColumnNum, CommentText);

【讨论】:

    【解决方案2】:

    您的 SQL 字符串包含:

    INSERT INTO [tb_dies] ([TOOL_ID], [DESCRIPTION], [RACK], [COLUMN], [COMMENTS]) 
    VALUES (-1,temp,temp,12,temp,temp)
    

    这不是有效的 SQL - 现在数据库服务器会将出现的 temp 视为变量或列名; temp 可能需要使用单撇号(意思是“字符串”),如下所示:

    INSERT INTO [tb_dies] ([TOOL_ID], [DESCRIPTION], [RACK], [COLUMN], [COMMENTS]) 
    VALUES (-1,'temp','temp',12,'temp','temp')
    

    因此您可能希望您的 VB 是:

    tempStr = "'test'"
    

    PS;作为 MS Access,标准 SQL 有可能不起作用,并且单个撇号不用于字符串。如果用双引号 " 表示访问中的字符串,您将看到 VBlike:

    tempStr = """test"""
    

    评论者提出了有效的观点;你不应该使用字符串连接来构建 SQL 查询。现在值得阅读http://bobby-tables.com 以获取一些关于它为什么不好的背景信息,然后你将更有能力走上软件开发的道路避免编写容易受到这种特殊(和常见)黑客攻击的软件

    【讨论】:

    • 谢谢,问题解决了。我为每个字符串参数添加了 """ & tool_temp & """ (两对双引号)
    • 开放SQL注入!如果变量没有被清理!
    • 我同意@xQbert,尽管我从来不知道在 Access 数据库上使用 SQL 注入。如果您担心注入攻击,您应该考虑使用 Access 以外的其他工具。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 2021-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多