错误使用ADO连接捕获代码

时间:2017-01-24 19:22:53

标签: sql vba

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

1 个答案:

答案 0 :(得分: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参数将包含有关它的所有详细信息:

Object Browser showing members of ADODB.Error class

假设类模块名为DbConnection,那么您可以像这样使用它:

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

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