运行时错误' 3144':更新语句

时间:2018-03-27 17:46:21

标签: sql vba access-vba

我遇到了更新语句的一些问题,Add语句似乎有效,但我在更新时遇到语法错误。我是SQL和VBA的新手,所以很多这可能看起来像sphagetti代码。如果有人能够确定我做错了什么,那将非常感激。如果有更好的方法,请告诉我。

Private Sub btnSubmit_Click()
Dim mbrName As String
Dim mbrOffice As String
Dim mbrRank As String
Dim mbrOpType As String
Dim mbrRLA As String
Dim mbrMQT As String
Dim mbrPos As String
Dim sqlAdd As String
Dim sqlUpdate As String
If Me.opgMngRoster.Value = 1 Then

    '-Set Middle Name to NMI if blank
    If IsNull(Me.txtMidInit.Value) Then
        Me.txtMidInit.Value = "NMI"
    End If

    '-Create Member's Name string in all uppercase
    mbrName = UCase(Me.txtLastName.Value & ", " & Me.txtFirstName.Value & " " & Me.txtMidInit)

    '-Member's Office
    mbrOffice = Me.cbxOffice.Value

    '-Member's Rank
    mbrRank = Me.cbxRank.Value

    '-Member's Operator Type
    mbrOpType = Me.cbxOpType

    '-Member's RLA
    mbrRLA = Me.cbxRLA.Value

    '-Member's MQT Program
    mbrMQT = Me.cbxMQT.Value

    '-Member's MQT Position
    mbrPos = Me.cbxTngPos.Value


    'ADD MEMBER TO ROSTER
    sqlAdd = "INSERT INTO [ROSTER] (MEMBER, OFFICE, RANK, OPTYPE, RLA, [MQT-PROGRAM], [MQT-POSITION]) VALUES ('" & mbrName & "', '" & mbrOffice & "', '" & mbrRank & "', '" & mbrOpType & "', '" & mbrRLA & "', '" & mbrMQT & "', '" & mbrPos & "');"
    DoCmd.RunSQL (sqlAdd)

    '-Confirmation Msg
    MsgBox ("Added: " & mbrName)

Else

    '-Set Middle Name to NMI if blank
    If IsNull(Me.txtMidInit.Value) Then
        Me.txtMidInit.Value = "NMI"
    End If

    '-Create Member's Name string in all uppercase
    mbrName = UCase(Me.txtLastName.Value & ", " & Me.txtFirstName.Value & " " & Me.txtMidInit)

    '-Member's Office
    mbrOffice = Me.cbxOffice.Value

    '-Member's Rank
    mbrRank = Me.cbxRank.Value

    '-Member's Operator Type
    mbrOpType = Me.cbxOpType

    '-Member's RLA
    mbrRLA = Me.cbxRLA.Value

    '-Member's MQT Program
    mbrMQT = Me.cbxMQT.Value

    '-Member's MQT Position
    mbrPos = Me.cbxTngPos.Value

    'Update Member Data
    sqlUpdate = "UPDATE [ROSTER] (MEMBER, OFFICE, RANK, OPTYPE, RLA, [MQT-PROGRAM], [MQT-POSITION]) VALUES ('" & mbrName & "', '" & mbrOffice & "', '" & mbrRank & "', '" & mbrOpType & "', '" & mbrRLA & "', '" & mbrMQT & "', '" & mbrPos & "');"
    Debug.Print sqlUpdate

    DoCmd.RunSQL sqlUpdate

    MsgBox ("Updated: " & mbrName)
End If
End Sub

1 个答案:

答案 0 :(得分:2)

您的设置存在几个常规编码和特定MS Access问题:

  1. 首先,无需为IfElse块重复VBA变量分配。使用DRY-er代码( D on't R epeat Y 我们自己)。

  2. 此外,由于您不应用进一步的计算,因此无需将大部分表单文本框和组合框值分配给单独的字符串变量。直接在查询中使用控制值。

  3. 使用参数化(行业最佳实践),它不仅适用于MS Access,而且适用于任何数据库在应用程序层(VBA,Python,PHP,Java等)中使用动态SQL的任何地方(Postgres,SQL)服务器,Oracle,SQLite等)。您可以避免注入和任何混乱的引用封装和数据连接。

    虽然语言有不同的方法将值绑定到参数,但MS Access中的一种方法是使用querydef parameters,如下所示。

  4. 使用PARAMETERS子句将查询保存为存储对象(仅在MS Access SQL方言中符合)。这有助于从数据中抽象代码。

  5. 最后,正确使用更新查询语法:UPDATE <table> SET <field>=<value> ...

  6. 插入SQL查询 (带参数化,保存一次作为存储查询)

    PARAMETERS MEMBER_Param TEXT, OFFICE_Param TEXT, RANK_Param TEXT, OPTYPE_Param TEXT, 
               RLA_Param TEXT, MQT_PROGRAM_Param TEXT, MQT_POSITION_Param TXT;
    INSERT INTO [ROSTER] (MEMBER, OFFICE, RANK, OPTYPE, RLA, [MQT-PROGRAM], [MQT-POSITION]) 
    VALUES (MEMBER_Param, OFFICE_Param, RANK_Param, OPTYPE_Param, 
            RLA_Param, MQT_PROGRAM_Param, MQT_POSITION_Param);
    

    更新SQL查询 (带参数化,保存一次作为存储查询)

    PARAMETERS MEMBER_Param TEXT, OFFICE_Param TEXT, RANK_Param TEXT, OPTYPE_Param TEXT, 
               RLA_Param TEXT, MQT_PROGRAM_Param TEXT, MQT_POSITION_Param TXT;
    UPDATE [ROSTER]
    SET MEMBER = MEMBER_Param, OFFICE = OFFICE_Param, RANK = RANK_Param, 
        OPTYPE = OPTYPE_Param, RLA = RLA_Param, [MQT-PROGRAM] =  MQT_PROGRAM_Param, 
        [MQT-POSITION] = MQT_POSITION_Param;
    

    VBA (未显示SQL)

    Dim mbrName As String, myquery As String, mymsg As String
    Dim qdef As QueryDef
    
    '-Set Middle Name to NMI if blank
    If IsNull(Me.txtMidInit.Value) Then
        Me.txtMidInit.Value = "NMI"
    End If
    
    '-Create Member's Name string in all uppercase
    mbrName = UCase(Me.txtLastName.Value & ", " & Me.txtFirstName.Value & " " & Me.txtMidInit)
    
    If Me.opgMngRoster.Value = 1 Then   
        myquery = "myRosterInsertQuery"
        mymsg = "Added: " & mbrName
    Else
        myquery = "myRosterUpdateQuery"
        mymsg = "Updated: " & mbrName
    End If
    
    ' ASSIGN TO STORED QUERY
    Set qdef = CurrentDb.QueryDefs(myquery)
    
    ' BIND PARAMS
    qdef!MEMBER_Param = mbrName  
    qdef!OFFICE_Param = Me.cbxOffice.Value
    qdef!RANK_Param = Me.cbxRank.Value
    qdef!OPTYPE_Param = Me.cbxOpType
    qdef!RLA_Param = Me.cbxRLA.Value
    qdef!MQT_PROGRAM_Param = Me.cbxMQT.Value
    qdef!MQT_POSITION_Param = Me.cbxTngPos.Value
    
    qdef.Execute dbFailOnError
    
    '-Confirmation Msg
    MsgBox mymsg, vbInformation
    
    Set qdef = Nothing
    
相关问题