检测某些记录是否从INSERT INTO操作中排除

时间:2013-11-15 15:09:19

标签: sql vba ms-access error-handling access-vba

我在INSERTing的表中的2列上有一个复合主键。我来自使用SQL Server,我知道如果我试图在PK表中插入重复的键值,它会引发错误。

我的问题是,我的代码没有抛出这种错误。你能看一下它,看看代码是否有问题?或者Access不会因此类违规而抛出错误吗?

[编辑]

我想我正在寻找一种方法来承认尝试插入重复记录。我希望保留当前功能(重复被抛出;插入有效记录)。我不希望整个INSERT被回滚。

我的代码如下。

Function InsertData(Ignore As String)  

    ' define file path of CSV to be imported
    Dim CurrentDate As String
    Dim CurrentYear As String

    CurrentDate = Format(Date, "yyyymmdd")
    CurrentYear = Format(Date, "yyyy")


    Dim Exfile As String
    Exfile = iPath + "\" + CurrentYear + "\" + "FileName" + CurrentDate + ".txt"

    'this calls a saved import routine
    DoCmd.RunSavedImportExport "tbl_TEMP"


    'merge data with that already existing in tbl_Perm.
    'the clustered PK on product_ID and As_of_Date prevents dup insertion
    Dim dbs As Database
    Dim errLoop As Error

    Set dbs = OpenDatabase(iPath + "\ExDatabase.mdb")
        dbs.Execute " INSERT INTO tbl_Perm (Col1,Col2,Date_Created) " _
                    & "SELECT ColA + ColB, ColC, Format$(Now(),'Short Date')" _
                    & "FROM tbl_TEMP;"

        ' Trap for errors, checking the Errors collection if necessary.
        On Error GoTo Err_Execute

        'delete temp table
        dbs.Execute "DROP TABLE tbl_TEMP;"

    dbs.Close

Err_Execute:
    ' Notify user of any errors that result from
    ' executing the query.
    If DBEngine.Errors.Count > 0 Then
    For Each errLoop In DBEngine.Errors
    MsgBox "Error number: " & errLoop.Number & vbCr & _
    errLoop.Description
    Next errLoop
    End If
 Resume Next

End Function

3 个答案:

答案 0 :(得分:2)

从Microsoft DAO Doc(here):

  

在Microsoft Access工作区中,如果您提供语法   正确的SQL语句并具有相应的权限   Execute方法不会失败 - 即使不能修改单行   或删除。因此,使用时始终使用dbFailOnError选项   用于运行更新或删除查询的Execute方法。这个选项   生成运行时错误并回滚所有成功的更改,如果   受影响的任何记录都已锁定且无法更新或   删除。

因此,请为您的通话添加dbFailOnError选项。

答案 1 :(得分:1)

如果您想允许INSERT继续并确定是否有任何重复项被拒绝,那么您可以执行类似这样的操作

Dim cdb As DAO.Database, qdf As DAO.QueryDef, rst As DAO.Recordset
Dim sqlSelect As String, sourceRecords As Long
Set cdb = CurrentDb
sqlSelect = _
        "SELECT ColA + ColB, ColC, Format$(Now(),'Short Date') " & _
        "FROM tbl_TEMP"
Set rst = cdb.OpenRecordset("SELECT COUNT(*) AS n FROM (" & sqlSelect & ")", dbOpenSnapshot)
sourceRecords = rst!n
rst.Close
Set rst = Nothing
Set qdf = cdb.CreateQueryDef("", _
        "INSERT INTO tbl_Perm (Col1,Col2,Date_Created) " & sqlSelect)
qdf.Execute
If qdf.RecordsAffected < sourceRecords Then
    Debug.Print sourceRecords - qdf.RecordsAffected & " record(s) not inserted"
End If
Set qdf = Nothing
Set cdb = Nothing

答案 2 :(得分:1)

该行

On Error GoTo Err_Execute

是在执行SQL语句之后。在这种情况下,每次都会调用 Err_Execute 块,因为标签之前没有Exit Function之类的语句。如果在评估错误集合之前关闭连接,我不确定错误会发生什么。