VBA错误3134 INSERT INTO语句中的语法错误

时间:2014-05-29 08:42:43

标签: sql vba ms-access

我已经开始支持/升级MS Access系统。我创建了一个表单,将现有项目中的记录复制到相同表格的新创建项目。我正在为2张桌子做这个。代码工作导入第一个表的记录,但给出了第二个表的错误。代码如下:

Private Sub cmdImportMaterials_Click()
    '---------------------------------------------------------------------------------------
    ' Procedure : cmdImportMaterials_Click
    ' Author    : kelly
    ' Date      : 26/05/2014
    ' Purpose   : Import materials to the current task from existing materials associated to the selected task.
    '---------------------------------------------------------------------------------------
    '

    On Error GoTo cmdImportMaterials_Click_Error
        Dim iCboTaskID As Integer
        Dim iImportTaskID As Integer
        Dim sMaterialsSql As String
        Dim sMatAddSql As String
        Dim db As Database
        Dim rstMat As Recordset
        Dim rstMatAdd As Recordset
        Dim sInsertMatSql As String
        Dim sInsertMatAddSql As String
        Dim sCust As String
        Dim iJobNo As Integer



    If IsNull(Me.cboTaskID.Value) Then
        MsgBox "Please select a task to import materials from"
    Else
        iCboTaskID = Me.cboTaskID.Column(0)
        sCust = Me.cboTaskID.Column(1)
        iJobNo = Me.cboTaskID.Column(2)
        sMaterialsSql = "Select * from MaterialRequisition Where TaskID = " & iCboTaskID & ";"
        sMatAddSql = "Select * from MaterialRequisitionAdditional Where TaskID = " & iCboTaskID & ";"
        Set db = CurrentDb()
        Set rstMat = db.OpenRecordset(sMaterialsSql)
        Set rstMatAdd = db.OpenRecordset(sMatAddSql)

        If rstMat.RecordCount = 0 And rstMatAdd.RecordCount = 0 Then
            MsgBox "There are no materials to import. Please select a task with materials."
        Else
            iImportTaskID = Forms![Task List].ID
            Select Case MsgBox("Are you sure you want to import the materials from " & sCust & "; Job #: " & iJobNo, vbYesNo)
                Case vbYes
                    DoCmd.SetWarnings False

                    'Add selected Additional materials to current task
                    If Not rstMat.EOF Then rstMat.MoveFirst
                    Do While Not rstMat.EOF
                        sInsertMatSql = "INSERT INTO MaterialRequisition ( TaskID, MatterialsListProductID, ItemQuantity, " _
                            & "Comments, Category, Description, ItemCode, Supplier, Price, Unit) " _
                            & "VALUES (" & iImportTaskID & ", " & rstMat("MatterialsListProductID") & ", " & rstMat("ItemQuantity") _
                            & ", """ & rstMat("Comments") & """, " & rstMat("Category") & ", """ & rstMat("Description") _
                            & """, """ & rstMat("ItemCode") & """, """ & rstMat("Supplier") & """, " & rstMat("Price") _
                            & ", """ & rstMat("Unit") & """);"
                        Debug.Print sInsertMatSql
                        DoCmd.RunSQL (sInsertMatSql)
                        rstMat.MoveNext
                    Loop
                    rstMat.Close
                    Set rstMat = Nothing

                    'Add selected Additional materials to current task
                    Debug.Print sMatAddSql
                    If Not rstMatAdd.EOF Then rstMatAdd.MoveFirst
                    Do While Not rstMatAdd.EOF
                        sInsertMatAddSql = "INSERT INTO MaterialRequisitionAdditional ( TaskID, ItemDescription, ItemQuantity, " _
                            & "Comments, Category, Description, ItemCode, Supplier, Price, Unit) " _
                            & "VALUES (" & iImportTaskID & ", """ & rstMatAdd("ItemDescription") & """, " & rstMatAdd("ItemQuantity") _
                            & ", """ & rstMatAdd("Comments") & """, " & rstMatAdd("Category") & ", """ & rstMatAdd("Description") _
                            & """, """ & rstMatAdd("ItemCode") & """, """ & rstMatAdd("Supplier") & """, " & rstMatAdd("Price") _
                            & ", """ & rstMatAdd("Unit") & """);"
                        Debug.Print sInsertMatAddSql
                        DoCmd.RunSQL (sInsertMatAddSql)
                        rstMatAdd.MoveNext
                    Loop
                    DoCmd.SetWarnings True
                    rstMatAdd.Close
                    Set rstMatAdd = Nothing
                    Set db = Nothing

                Case vbNo
                    MsgBox "No selected" 'Do nothing
                End Select
        End If

    End If

Exit_cmdImportMaterials_Click:
    Exit Sub

cmdImportMaterials_Click_Error:

    DoCmd.SetWarnings True

    MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure cmdImportMaterials_Click of VBA Document Form_frmMatReqListImport"

    Debug.Print "#" & Err.Number, Err.Description, "cmdImportMaterials_Click", "Form_frmMatReqListImport"

    Resume Exit_cmdImportMaterials_Click

End Sub

为每个Sql字符串生成的SQL如下: (除了MatterialsListProductID是数字且ItemDescription是文本外,两个语句的字段类型相同)

sInsertMatSql

INSERT INTO MaterialRequisition ( TaskID, MatterialsListProductID, ItemQuantity, Comments, Category, Description, ItemCode, Supplier, Price, Unit) VALUES (2956, 131, 300, "", 15, "M8 X 65 FEET", "FET-00000000131", "SPRINGLOK                               ", 2.18, "each");

sInsertMatAddSql

INSERT INTO MaterialRequisitionAdditional ( TaskID, ItemDescription, ItemQuantity, Comments, Category, Description, ItemCode, Supplier, Price, Unit) VALUES (2956, "4MM WIRE", 1860, "METRES", , "", "", "", , "");

2 个答案:

答案 0 :(得分:0)

从您的第一个查询中,我可以看到CategoryPrice列包含数字数据类型(您正在插入数值)。

在第二个查询中,您尝试在这些列中插入(甚至不是NULL - 没有):

... VALUES (2956, "4MM WIRE", 1860, "METRES", , "", "", "", , "")

                                             ↑             ↑
                                            here        and here

如果您不想在这些列中插入任何内容,请尝试使用以下解决方案之一:

  1. 完全省略列(在命名列的列表值列表中)
  2. 如果列可以为空,则插入NULL
  3. 插入0

答案 1 :(得分:0)

在我看来,你正在做很多循环(低效)和#34; SQL粘合" (丑陋且容易出错)当你真正需要做的就是这样的事情:

Dim qdf As DAO.QueryDef
Set qdf = db.CreateQueryDef("", _
        "INSERT INTO MaterialRequisition ( TaskID, MatterialsListProductID, ItemQuantity, " & _
        "Comments, Category, Description, ItemCode, Supplier, Price, Unit) " & _
        "SELECT [newTaskID] AS TaskID, MatterialsListProductID, ItemQuantity, " & _
        "Comments, Category, Description, ItemCode, Supplier, Price, Unit " & _
        "FROM MaterialRequisition WHERE TaskID = [oldTaskID]")
qdf!oldTaskID = iCboTaskID
qdf!newTaskID = iImportTaskID
qdf.Execute
Set qdf = Nothing

这将复制[oldTaskID]中的所有[MaterialRequisition]记录,并将它们插入[newTaskID]下的表中。