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

Database Docmd.RunSql运行时错误';3464';-更新查询,database,vba,ms-access,Database,Vba,Ms Access,我正在尝试使用简单的VBA代码更新access表,但是它以一个错误结束。我尝试过各种方法来解决这个问题,但没有成功。 你能帮忙吗?代码如下: strSQL = "UPDATE Projects " & _ "SET Projects.id_status = '" & Me.T_project_s.Value & "' " & _ "WHERE Projects.id_project = '" & Me.curr_op

我正在尝试使用简单的VBA代码更新access表,但是它以一个错误结束。我尝试过各种方法来解决这个问题,但没有成功。 你能帮忙吗?代码如下:

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语句中,不需要在“”旁边加上“”:)


再次感谢。

这里有一个例子,参数化(SQL编程中的行业最佳实践)有助于避免SQL注入。与你一起:

  • 避免报价附件的需要
  • 避免变量的字符串插值
  • 从代码(即SQL语句)中提取数据(即VBA变量),用于更干净的脚本
  • (加上OP发现的混合类型)明确定义要绑定的值的数据类型
  • 通过DAO执行查询,以获得比向用户发出警告的
    DoCmd.RunSQL
    更平滑的用户界面
  • 临时查询

    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
    
    保存的查询

    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中引用的任何常规查询对象)

    参数[项目参数]文本(255),[当前打开参数]长;
    更新[项目]
    设置[项目].[id\U状态]=[项目参数]
    其中[Projects].[id_project]=[curr_open_param]
    
    VBA


    用实际值替换变量时,sql有效吗?示例:
    strSQL=“updateprojects SET Projects.id\u status='3',其中Projects.id\u project='1'”
    此外:您的字段名意味着您正在使用id(通常是数字),而sql正在更新字符串(带引号)。那么您的问题解决了吗?如果是,请发布答案或关闭问题。
    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
    
    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