Error Trapping code using ADO connections

后端 未结 1 645
隐瞒了意图╮
隐瞒了意图╮ 2020-12-22 07:02

As a standard practice, I think most know that an ADO connection and recordset needs to be closed after you\'ve gotten what you need from it. I hadn\'t really thought to mu

相关标签:
1条回答
  • 2020-12-22 07:36

    Using standard error trapping methods, the connection wouldn't get closed.

    Depends how you implement it. I usually do something like this:

    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
    

    I'd call it "standard error trapping", and it has yet to fail me.


    There are other ways though. ADODB.Connection has a pretty rich API that's quite seldom used. You could wrap it up in a class module and encapsulate it in a WithEvents field, like this:

    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
    

    I'd think if there's an error at any point, the pError parameter will include all the details about it:

    Object Browser showing members of ADODB.Error class

    Say that class module is named DbConnection, then you could use it like this:

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

    And whenever the object goes out of scope (whether End With was hit, or execution jumped out of the With block for whatever the reason), the Class_Terminate handler should run and ensure the encapsulated connection gets closed.

    0 讨论(0)
提交回复
热议问题