Проверьте, открыто ли соединение ADODB
Я использую следующее из некоторых процедур excel, чтобы установить соединение с нашей базой данных.
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
В следующем коде я открываю соединение, используя различные строки SQL.
Я бы хотел проверить, открыт ли rs
, поэтому я знаю, что его нужно закрыть, но следующее не работает. Как я могу изменить условие в следующем для работы?
If (rs.Open = True) Then
rs.Close
End If
Следующие действия, но я бы предпочел не использовать захват ошибок таким образом:
On Error Resume Next
rs.Close
Ответы
Ответ 1
У набора записей ADO есть свойство .State
, вы можете проверить, имеет ли его значение adStateClosed
или adStateOpen
If Not (rs Is Nothing) Then
If (rs.State And adStateOpen) = adStateOpen Then rs.Close
Set rs = Nothing
End If
MSDN о состоянии штата
Изменить;
Причина не проверять .State
на 1 или 0, потому что, даже если она работает 99.99% времени, все еще возможно установить другие флаги, которые оператор If не выполняет проверку adStateOpen
.
Edit2:
Для привязки Late без объектов ActiveX Data Objects, у вас есть несколько вариантов.
Используйте значение константы adStateOpen из ObjectStateEnum
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
Ответ 2
Эта тема старая, но если другие люди вроде меня ищут решение, это решение, которое я нашел:
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 дает вам false