【问题标题】:detecting whether some records are excluded from an INSERT INTO operation检测某些记录是否从 INSERT INTO 操作中排除
【发布时间】:2013-11-29 00:40:54
【问题描述】:

我在要插入的表中的 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

【问题讨论】:

    标签: sql ms-access error-handling vba


    【解决方案1】:

    来自 Microsoft DAO 文档 (here):

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

    所以在您的通话中添加dbFailOnError 选项。

    【讨论】:

    • 我的描述应该更清楚。我想我正在寻找一种方法来确认尝试插入重复记录。我希望保留当前功能(丢弃重复;插入有效记录)。我不希望整个 INSERT 回滚。
    • 那么我建议使用RcordsAffected 属性来查看插入的行数是否等于Select 预期的行数。
    【解决方案2】:

    如果您想允许 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
    

    【讨论】:

    • 哇——太棒了。一旦获得对数据库的独占控制权,我将尝试实施 :(
    【解决方案3】:

    线

    On Error GoTo Err_Execute
    

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

    【讨论】:

    • 对不起,我没有完全理解你。我应该将Exit Function 放在我的代码中的什么位置?
    • 你必须把On Error GoTo放在可能导致错误的代码之前,Exit Function放在Err_Execute-Block之前,否则每次都会执行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-15
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多