【问题标题】:Error Trapping code using ADO connections使用 ADO 连接的错误捕获代码
【发布时间】:2017-01-25 03:48:30
【问题描述】:

作为一种标准做法,我认为大多数人都知道,在获得所需内容后,需要关闭 ADO 连接和记录集。过去我并没有真正考虑过它,但我只是变得好奇。当您使用 ADO 连接到数据库时,错误捕获的正确方法是什么?我问是因为如果您在连接仍然打开时产生错误,使用标准错误捕获方法,连接不会关闭。我想这会导致内存问题。

【问题讨论】:

    标签: sql vba


    【解决方案1】:

    使用标准错误捕获方法,连接不会关闭。

    取决于你如何实现它。我通常会这样做:

    Public Sub DoSomething()
        On Error GoTo CleanFail
    
        Dim conn As ADODB.Connection
        Set conn = New ADODB.Connection
        conn.Open
    
        ' do stuff
    
    CleanExit:
        If Not conn Is Nothing Then conn.Close
        Exit Sub
    CleanFail:
        ' handle errors - rollback transaction, etc.
        Resume CleanExit
    End Sub
    

    我称之为“标准错误捕获”,它还没有让我失望。


    还有 其他方式。 ADODB.Connection 有一个非常丰富但很少使用的 API。您可以将其包装在一个类模块中并将其封装在 WithEvents 字段中,如下所示:

    Option Explicit
    
    Private WithEvents MyConnection As ADODB.Connection
    Private Const MyConnectionString As String = ""
    
    Private Sub Class_Initialize()
        Set MyConnection = New ADODB.Connection
        MyConnection.ConnectionString = MyConnectionString
        MyConnection.Open
    End Sub
    
    Private Sub Class_Terminate()
        If MyConnection Is Nothing Then Exit Sub
        MyConnection.Close
        Set MyConnection = Nothing
    End Sub
    
    ' public members...
    
    Private Sub MyConnection_BeginTransComplete(ByVal TransactionLevel As Long, ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
        Debug.Print "BeginTransComplete"
    End Sub
    
    Private Sub MyConnection_CommitTransComplete(ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
        Debug.Print "CommitTransComplete"
    End Sub
    
    Private Sub MyConnection_ConnectComplete(ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
        Debug.Print "ConnectComplete"
    End Sub
    
    Private Sub MyConnection_Disconnect(adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
        Debug.Print "Disconnect"
    End Sub
    
    Private Sub MyConnection_ExecuteComplete(ByVal RecordsAffected As Long, ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset, ByVal pConnection As ADODB.Connection)
        Debug.Print "ExecuteComplete"
    End Sub
    
    Private Sub MyConnection_InfoMessage(ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
        Debug.Print "InfoMessage"
    End Sub
    
    Private Sub MyConnection_RollbackTransComplete(ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
        Debug.Print "RollbackTransComplete"
    End Sub
    
    Private Sub MyConnection_WillConnect(ConnectionString As String, UserID As String, Password As String, Options As Long, adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
        Debug.Print "WillConnect"
    End Sub
    
    Private Sub MyConnection_WillExecute(Source As String, CursorType As ADODB.CursorTypeEnum, LockType As ADODB.LockTypeEnum, Options As Long, adStatus As ADODB.EventStatusEnum, ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset, ByVal pConnection As ADODB.Connection)
        Debug.Print "WillExecute"
    End Sub
    

    我认为如果在任何时候出现错误,pError 参数将包含有关它的所有详细信息:

    假设类模块被命名为DbConnection,那么你可以这样使用它:

    Public Sub DoSomething()
        With New DbConnection
            'do stuff
        End With
    End Sub
    

    并且每当对象超出范围时(无论是End With 是否被命中,或者无论出于何种原因执行跳出With 块),Class_Terminate 处理程序都应该运行并确保封装的连接关闭。

    【讨论】:

    • 这样做是有道理的,但如果你有多个嵌套的记录集,它会变得非常混乱。
    • @Addohm 如果您有嵌套的记录集,那么您的代码可能可以简化为进行单个查询。我从来没有见过一团糟的嵌套记录集。
    • @Addohm 您可能需要查看并根据您的目的调整代码审查中的Materializing any ADODB queryCreating ADODB parameters on the fly - 它大大简化了 ADO 代码。希望对您有所帮助!
    • 我去看看,谢谢!我已经考虑过减轻 ADODB 查询编码负担的方法,但我不必像现在在这个项目中那样经常这样做。
    • 我看到你写的。您是否有某种形式的 VBA 代码文件(excel?)来显示您编写的内容的基线结构和布局?
    猜你喜欢
    • 2015-12-02
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    相关资源
    最近更新 更多