【发布时间】:2017-01-25 03:48:30
【问题描述】:
作为一种标准做法,我认为大多数人都知道,在获得所需内容后,需要关闭 ADO 连接和记录集。过去我并没有真正考虑过它,但我只是变得好奇。当您使用 ADO 连接到数据库时,错误捕获的正确方法是什么?我问是因为如果您在连接仍然打开时产生错误,使用标准错误捕获方法,连接不会关闭。我想这会导致内存问题。
【问题讨论】:
作为一种标准做法,我认为大多数人都知道,在获得所需内容后,需要关闭 ADO 连接和记录集。过去我并没有真正考虑过它,但我只是变得好奇。当您使用 ADO 连接到数据库时,错误捕获的正确方法是什么?我问是因为如果您在连接仍然打开时产生错误,使用标准错误捕获方法,连接不会关闭。我想这会导致内存问题。
【问题讨论】:
使用标准错误捕获方法,连接不会关闭。
取决于你如何实现它。我通常会这样做:
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 处理程序都应该运行并确保封装的连接关闭。
【讨论】: