Docmd.RunSql运行时错误' 3464' - 更新查询

时间:2017-10-09 08:35:00

标签: database vba ms-access

我正在尝试使用简单的VBA代码更新访问表,但是它完成了一个错误。我尝试了各种方法来解决它,但没有成功。 能否请你帮忙?代码如下:

strSQL = "UPDATE Projects " & _
          "SET Projects.id_status = '" & Me.T_project_s.Value & "' " & _
          "WHERE Projects.id_project = '" & Me.curr_open.Value & "';" 

我也尝试过:

strSQL = "UPDATE Projects " & _
          "SET Projects.id_status = [" & Me.T_project_s.Value & "] " & _
          "WHERE Projects.id_project = [" & Me.curr_open.Value & "];"

strSQL = "UPDATE [Projects] " & _
          "SET [Projects].[id_status] = '" & Me.T_project_s.Value & "' " & _
          "WHERE [Projects].[id_project] = '" & Me.curr_open.Value & "';"

但它要求提供这些领域中可用的数据。

您的建议有所帮助。我从一个文本开始,然后我更改了我想要阅读的特定变量。所以在Where声明中没有必要旁边""也'' :)

strSQL = "UPDATE [Projects] " & _
          "SET [Projects].[id_status] = '" & Me.T_project_s.Value & "' " & _
          "WHERE [Projects].[id_project] = " & Me.curr_open.Value & ";"

感谢。

1 个答案:

答案 0 :(得分:1)

再一次,这里有一个例子,其中参数化(SQL编程中的行业最佳实践)有助于避免SQL注入。使用querydef parameters您:

  1. 避免引用封闭;
  2. 避免变量的字符串插值;
  3. 来自代码(即SQL语句)的抽象数据(即VBA变量),用于更清晰的脚本;
  4. (加上OP发现混合类型)明确定义要绑定的值的数据类型;
  5. 通过DAO执行查询,以获得比向用户发出警告的DoCmd.RunSQL更流畅的用户界面。
  6. 临时查询

    Dim qdef As QueryDef
    
    ' PREPARED STATEMENT, DEFINING PLACEHOLDERS (NO DATA)
    strSQL = "PARAMETERS [project_s_param] Text(255), [curr_open_param] Long;" & _
             " UPDATE [Projects]" & _
             " SET [Projects].[id_status] = [project_s_param]" & _
             " WHERE [Projects].[id_project] = [curr_open_param];" 
    
    ' CREATE UNNAMED TEMP QUERYDEF, ASSIGNING PREPARED STATEMENT
    Set qdef = CurrentDb.CreateQueryDef("", strSQL)
    
    ' BIND VBA VALUES TO PARAMETER PLACEHOLDERS
    qdef![project_s_param] = Me.T_project_s.Value
    qdef![curr_open_param] = Me.curr_open.Value
    
    ' EXECUTE ACTION
    qdef.Execute dbFailOnError
    
    Set qdef = Nothing
    

    保存的查询

    更好的是,将整个预准备语句保存为存储的Access查询,并避免在VBA中使用任何SQL。

    SQL (另存为名称在VBA中引用的任何常规查询对象)

    PARAMETERS [project_s_param] Text(255), [curr_open_param] Long;
    UPDATE [Projects]
    SET [Projects].[id_status] = [project_s_param]
    WHERE [Projects].[id_project] = [curr_open_param]
    

    VBA

    Dim qdef As QueryDef
    
    ' REFERENCE EXISTING QUERYDEF, ASSIGNING PREPARED STATEMENT
    Set qdef = CurrentDb.QueryDefs("mySavedQuery")
    
    ' BIND VBA VALUES TO PARAMETER PLACEHOLDERS
    qdef![project_s_param] = Me.T_project_s.Value
    qdef![curr_open_param] = Me.curr_open.Value
    
    ' EXECUTE ACTION
    qdef.Execute dbFailOnError
    
    Set qdef = Nothing