真的很快,我是否需要关闭ADO命令?我已经在几个地方读过,简单地将它设置为无关与关闭它同样的事情,但我还没有找到明确的答案。
我有一个VB6例程,它在运行时创建一个连接和命令对象,它异步执行一个不返回任何结果的存储过程。
在此例程结束时,两个对象都设置为空。以下代码显示了已执行的内容
' Open connection
con.Open
'
' Create command to execute stored proc
Set cmd = New ADODB.Command
cmd.ActiveConnection = con
cmd.CommandType = adCmdStoredProc
cmd.CommandText = cSQLDelete
cmd.Parameters.Append cmd.CreateParameter _
("@ExpiryDate=", adDate, adParamInput, 20, ExpiryDate)
'
' Run procedure, no results
cmd.Execute , , adExecuteNoRecords + adAsyncExecute
'
' Tidy up
Set cmd = Nothing
Set con = Nothing
注意没有con.Close。如果在con = nothing之前插入它,则存储过程不会运行 - 我认为因为它是异步的,所以在连接关闭之前没有时间执行。
没有con.Close,这样可以正常工作。
所以,我的问题是没有关闭连接有什么影响。连接会在后台暂停吗?请记住,此功能称为A LOT,到目前为止,测试未显示任何问题。
如果我需要在存储过程完成时关闭连接,我该怎么做?拥有C#背景,我不熟悉VB6,并且发现在运行时创建具有事件的对象是一个尴尬的过程。
P.S。 Sql Server 2008
由于
答案 0 :(得分:1)
在拆除连接之前,您必须等待命令完成或失败。执行命令时关闭连接会立即引发错误,将连接设置为空,不会释放它所持有的资源,并可能导致程序崩溃。
正确的方法是在命令完成时关闭连接,通常是通过监视ExecuteComplete事件(您的连接必须属于类或表单)。
你可以使用类似的东西:
Option Explicit
Dim WithEvents con As ADODB.Connection
Dim bExecuting As Boolean
Private Sub cmdCancel_Click()
If Not bExecuting Then Exit Sub
If Not con Is Nothing Then
con.Cancel
End If
bExecuting = False
End Sub
Private Sub cmdExecute_Click()
If bExecuting Then Exit Sub
If con Is Nothing Then
Set con = New ADODB.Connection
con.Open "Provider=..."
End If
bExecuting = True
con.Execute "WAITFOR DELAY '000:00:10'", , adExecuteNoRecords + adAsyncExecute
End Sub
Private Sub cmdExit_Click()
If bExecuting Then Exit Sub
Unload Me
End Sub
Private Sub con_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)
If Not pError Is Nothing Then Debug.Print pError.Description
bExecuting = False
End Sub
Private Sub Form_Load()
bExecuting = False
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
If bExecuting Then Cancel = 1
End Sub
Private Sub Form_Unload()
If Not con Is Nothing Then
If con.State = adStateOpen Then con.Close
set con = Nothing
End If
End Sub
答案 1 :(得分:1)
如果连接不忙(State = Open),此代码执行的操作是执行命令。否则将其放在堆栈上并在当前命令完成时执行它。我对VB数组的了解有限,很遗憾它有点难看 - 有可能有更好的方法来进行FIFO队列吗?
Dim WithEvents mobjAdoConn As ADODB.Connection
Dim CommandArray() As String
Private Sub Command1_Click()
Dim cmdNo As Integer
If mobjAdoConn.State <> adStateOpen Then
cmdNo = UBound(CommandArray)
ReDim Preserve CommandArray(cmdNo + 1)
CommandArray(cmdNo) = "WAITFOR DELAY '000:00:10'"
Label2.Caption = cmdNo
Else
mobjAdoConn.Execute "WAITFOR DELAY '000:00:10'", , adExecuteNoRecords + adAsyncExecute
End If
End Sub
Private Sub Form_Load()
On Error GoTo Err
Set mobjAdoConn = New ADODB.Connection
mobjAdoConn.ConnectionTimeout = 30
mobjAdoConn.ConnectionString = "Provider..."
mobjAdoConn.Open
ReDim CommandArray(1)
Exit Sub
Err:
MsgBox Err.Description, vbOKOnly
End Sub
Private Sub mobjAdoConn_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)
Dim cmd As String
Dim i As Integer
Dim cmds As Integer
cmds = UBound(CommandArray)
If cmds > 1 Then
cmd = CommandArray(1)
If cmds = 2 Then
ReDim CommandArray(1)
Label2.Caption = 0
Else
For i = 2 To cmds - 1
CommandArray(i - 1) = CommandArray(i)
Next i
ReDim Preserve CommandArray(cmds - 1)
Label2.Caption = cmds - 2
End If
mobjAdoConn.Execute cmd, , adExecuteNoRecords + adAsyncExecute
End If
End Sub
答案 2 :(得分:0)
我在这里是因为我考虑在类似的实时应用程序中使用asynchExecute。在打开时将连接设置为空的问题是它可能无法正确释放,并且每创建一个新的10M,这可能会导致内存泄漏。 Mucker你应该在测试它时监视内存使用情况,看它是否发生。