ADO (Microsoft ActiveX Data Objects 6.1 Library)를 사용하여 연결하는 여러 데이터베이스에 의존하는 Excel 기반 응용 프로그램이 있습니다. 데이터베이스는 지역 서버에 상주하며 재사용을 위해 Scripting.Dictionary 객체에 연결을 캐시 할 수 있도록 초기 연결을 설정하는 데 오버 헤드가 있습니다. VBA에 KDB +/qodbc.dll이있는 ADO
Private moConnCacheDict As Scripting.Dictionary
나는 KDB + qodbc.dll 데이터베이스 드라이버를 사용
나는 예기치 않은 동작을 얻을. 여러 데이터 소스 (Oracle, Sybase, Access)와 하나의 KDB 데이터베이스 인스턴스를 예상대로 연결하여 재사용 할 수 있습니다. 그러나 두 번째 KDB 데이터베이스 연결을 만들고 새 데이터 집합에 대해 쿼리를 실행하면 쿼리가 합법적이라고하더라도 데이터가 반환되지 않습니다.Recordset.BOF = TRUE and Recordset.EOF = TRUE
잘 실행되고 필드가 표시됩니다. 이전 지역 서버로의 연결이 유지 보인다 나는 성공적으로 내가 보면 사실에도 불구하고 원래 서버에있는 데이터,
Recordset.ActiveCommand.ActiveConnection.Properties.Item("Extended Properties")
, 새로운 연결 문자열이를 검색 할 수 있습니다.
산은 + 연결 문자열 다음 구문 사용 다음 ADO.Recordset 항상 폐쇄 설정 참고
Private Function ExecuteQuery(sDBName As String, ByRef oRst As ADODB.Recordset, Optional bDeleteConnection As Boolean) As Boolean
Dim oDBConn As ADODB.Connection
Dim sSql As String
'delete connection
If bDeleteConnection Then Call DropConnection(sDBName)
'get cached or new connection
Call GetConnection(sDBName, oDBConn)
Select Case sDBName
Case "MAIN_US"
sSql = mSQL_MAIN
Case "MD_ASIA"
sSql = mSQL_MDASIA
End Select
Set oRst = New Recordset
oRst.Open sSql, oDBConn, adOpenKeyset, adLockPessimistic
If Not oDBConn.State = adStateOpen Then Err.Raise vbObjectError + 1024, "ExecuteQuery", sDBName & ": Recordset Closed. Unable to execute query ->" & sSql
ExecuteQuery = True
End Function
Private Function GetConnection(sDBName As String, ByRef oDBConn As ADODB.Connection) As Boolean
If moConnCacheDict Is Nothing Then Set moConnCacheDict = New Dictionary
If moConnCacheDict.Exists(sDBName) Then
'get existing connection
Set oDBConn = moConnCacheDict.Item(sDBName)
Else
'create connection
Set oDBConn = New Connection
With oDBConn
.Mode = adModeRead
Select Case sDBName
Case "MAIN_US"
.Mode = adModeReadWrite
.ConnectionString = mCONN_MAIN
Case "MD_ASIA"
.Mode = adModeRead
.ConnectionString = mCONN_MDASIA
End Select
.CursorLocation = adUseServer
.Open
End With
moConnCacheDict.Add sDBName, oDBConn
End If
GetConnection = True
End Function
Private Function DropConnection(Optional sDBName As String) As Boolean
Dim oDBConn As ADODB.Connection
Dim i As Integer
'delete object directly from cache
If Not moConnCacheDict Is Nothing Then
If sDBName = vbNullString Then
'close all connections
For i = 0 To moConnCacheDict.Count - 1
If Not IsEmpty(moConnCacheDict.Items(i)) Then
Set oDBConn = moConnCacheDict.Items(i)
If Not oDBConn Is Nothing Then
If oDBConn.State = adStateOpen Then oDBConn.Close
Set oDBConn = Nothing
Debug.Print Now, "Dropping Database Connection - " & moConnCacheDict.Keys(i)
End If
End If
Next i
Set moConnCacheDict = Nothing
Else
If moConnCacheDict.Exists(sDBName) Then
If Not IsEmpty(moConnCacheDict.Item(sDBName)) Then
Set oDBConn = moConnCacheDict.Item(sDBName)
If Not oDBConn Is Nothing Then
If oDBConn.State = adStateOpen Then oDBConn.Close
Set oDBConn = Nothing
Debug.Print Now, "Dropping Database Connection - " & "Dropping Database Connection - " & sDBName
End If
End If
moConnCacheDict.Remove (sDBName)
End If
End If
End If
DropConnection = True
End Function
(: I는 예를 들어 사용되는 코어 VBA 기능을 포함했다
DRIVER=kdb+;DBQ=XXXXX;UID=XXXXX;PWD=XXXXX;
을 호출자가 아무 것도하지 않음).
문제를 해결할 수있는 유일한 방법은 모든 데이터베이스 연결을 (공급자에 관계없이) 닫은 다음 원하는 지역 서버에 다시 연결하는 것입니다. 이것은 기존의 모든 연결을 다시 열어야하기 때문에 비효율적입니다. 또한 현재 통합 문서에서이 작업을 수행하는 것만으로는 충분하지 않습니다. 이 작업은 응용 프로그램 수준에서 수행해야합니다. ANY 데이터베이스에 대한 모든 ADO 연결이 아직 열려 있으면 새 KDB + ADO 연결을 만들 수 있지만 여전히 이전 인스턴스을 가리 킵니다.
나는 KDB + 연결 개체의 오류 속성을 보았다 두 개의 오류가 있습니다
- 여러 단계 OLE DB 작업을하는 동안 오류가 발생했습니다가. 가능한 경우 각 OLE DB 상태 값을 확인하십시오. 어떤 일도 행해지 지 않았다.
- 공급자가이 속성을 지원하지 않습니다.
이 내용은 http://support.microsoft.com/kb/269495에 문서화되어 있지만 레지스트리에 CLSID가 없으므로 제안 된 변경 사항을 시험 할 수 없습니다.
나는 다음과 같은 메시지가 나타나면 ODBC 로깅을 설정하는 경우 :
EXCEL 8dc-22d0 EXIT SQLGetInfoW with return code -1 (SQL_ERROR)
HDBC 0x02131EA8
UWORD 151 <SQL_KEYSET_CURSOR_ATTRIBUTES2>
PTR 0x003C4FB0
SWORD 4
SWORD * 0x00000000
DIAG [S1096] [Microsoft][ODBC Driver Manager] Information type out of range (0)
이 어쨌든 오류에 대한 책임을 질 것인가를?
언제나 그렇듯이 도움이나 제안을 많이 주시면 감사하겠습니다.
나에게 KDB + OLE DB 드라이버의 버그와 비슷합니다. 저의 제안은 * 최소한의 재현 가능한 예제를 생성하는 것입니다 (두 개의 KDB + 연결을 열고 두 번째 연결이 있어야 함을 보여주고 버그 리포트로 KDB + 개발자에게 보냅니다). – Heinzi