20

I use the following from within some excel procedures to establish a connection to our database.

Private Const strConn As String = _
    "PROVIDER=SQLOLEDB.1 ..."     

Sub OpenConnection()

Set cn = CreateObject("ADODB.Connection")
cn.Open strConn
cn.CommandTimeout = 0
Set rs = CreateObject("ADODB.Recordset")
Set rs.ActiveConnection = cn

End Sub 

In subsequent code I open the connection using various SQL strings.
I'd like to test if rs is open so I know that it needs to be closed but the following does not work. How can I change the condition in the following to work?

If (rs.Open = True) Then
    rs.Close
End If

The following works but I'd rather not use error trapping in this way:

On Error Resume Next
    rs.Close
4

3 回答 3

35

ADO Recordset 有.State属性,你可以检查它的值是adStateClosedadStateOpen

If Not (rs Is Nothing) Then
  If (rs.State And adStateOpen) = adStateOpen Then rs.Close
  Set rs = Nothing
End If

MSDN 关于状态属性

编辑; 不检查.State1 或 0 的原因是因为即使它在 99.99% 的时间内都有效,仍然有可能设置其他标志,这将导致 If 语句adStateOpen检查失败。

编辑2:

对于没有引用 ActiveX 数据对象的后期绑定,您几乎没有选择。使用ObjectStateEnum中的 adStateOpen 常量的值

If Not (rs Is Nothing) Then
  If (rs.State And 1) = 1 Then rs.Close
  Set rs = Nothing
End If

或者您可以自己定义常量以使您的代码更具可读性(将它们全部定义为一个很好的示例。)

Const adStateClosed As Long = 0 'Indicates that the object is closed.
Const adStateOpen As Long = 1 'Indicates that the object is open.
Const adStateConnecting As Long = 2 'Indicates that the object is connecting.
Const adStateExecuting As Long = 4 'Indicates that the object is executing a command.
Const adStateFetching As Long = 8 'Indicates that the rows of the object are being retrieved.    

[...]

If Not (rs Is Nothing) Then

    ' ex. If (0001 And 0001) = 0001 (only open flag) -> true
    ' ex. If (1001 And 0001) = 0001 (open and retrieve) -> true
    '    This second example means it is open, but its value is not 1
    '    and If rs.State = 1 -> false, even though it is open
    If (rs.State And adStateOpen) = adStateOpen Then 
        rs.Close
    End If

    Set rs = Nothing
End If
于 2013-07-12T09:33:43.493 回答
3

这是一个老话题,但万一其他人还在寻找......

在取消停靠事件后我遇到了麻烦。即使在重新连接到网络之后,保存在全局对象中的打开的数据库连接也会出错。这是由于远程主机强制终止 TCP 连接。(错误 -2147467259:TCP 提供程序:现有连接被远程主机强行关闭。)

但是,该错误只会在尝试第一次交易后出现。到那时, Connection.State 和 Connection.Version (根据上述解决方案)都不会显示任何错误。

所以我写了下面的小子来强制错误 - 希望它有用。

我的设置(Access 2016,SQL Svr 2008R2)的性能测试是每次调用大约 0.5 毫秒。

Function adoIsConnected(adoCn As ADODB.Connection) As Boolean

    '----------------------------------------------------------------
    '#PURPOSE: Checks whether the supplied db connection is alive and
    '          hasn't had it's TCP connection forcibly closed by remote
    '          host, for example, as happens during an undock event
    '#RETURNS: True if the supplied db is connected and error-free, 
    '          False otherwise
    '#AUTHOR:  Belladonna
    '----------------------------------------------------------------

    Dim i As Long
    Dim cmd As New ADODB.Command

    'Set up SQL command to return 1
    cmd.CommandText = "SELECT 1"
    cmd.ActiveConnection = adoCn

    'Run a simple query, to test the connection
    On Error Resume Next
    i = cmd.Execute.Fields(0)
    On Error GoTo 0

    'Tidy up
    Set cmd = Nothing

    'If i is 1, connection is open
    If i = 1 Then
        adoIsConnected = True
    Else
        adoIsConnected = False
    End If

End Function
于 2020-02-12T12:54:46.643 回答
1

这个话题很老,但是如果像我这样的其他人搜索解决方案,这是我找到的解决方案:

Public Function DBStats() As Boolean
    On Error GoTo errorHandler
        If Not IsNull(myBase.Version) Then 
            DBStats = True
        End If
        Exit Function
    errorHandler:
        DBStats = False  
End Function

所以“myBase”是一个数据库对象,我创建了一个类来访问数据库(带有插入、更新等的类),并且在模块上,该类在对象中使用声明(显然),我可以测试连接使用“[对象].DBStats”:

Dim BaseAccess As New myClass
BaseAccess.DBOpen 'I open connection
Debug.Print BaseAccess.DBStats ' I test and that tell me true
BaseAccess.DBClose ' I close the connection
Debug.Print BaseAccess.DBStats ' I test and tell me false

编辑:在 DBOpen 我使用“OpenDatabase”,在 DBClose 我使用“.Close”和“set myBase = nothing” 编辑 2:在函数中,如果你没有连接,.version 会给你一个错误,所以如果没有连接,errorHandler给你假

于 2016-01-12T15:14:23.797 回答