Te dwie instrukcje są podobne, ale druga powoduje awarię programu Excel za każdym razem, gdy jest wykonywana. Jedyna różnica jest między model
i model return updated rows
(mam specjalnie zaprojektowany ten minimalny przykład tak, że kwerendy powrócić dokładnie te same dane, w każdym przypadku, mój świecie rzeczywistym SQL różni się oczywiście):Jak mogę obejść awarie programu Excel z niektórymi instrukcjami SELECT?
select * from(select * from (select 1 id, 100 val from dual union all select 2 id, 200 val from dual) model dimension by (id) measures (val) rules (val[1] = val[cv()]+1)) where val=101
select * from(select * from (select 1 id, 100 val from dual union all select 2 id, 200 val from dual) model return updated rows dimension by (id) measures (val) rules (val[1] = val[cv()]+1)) where val=101
Czy to odosobniony przykład błąd w ADO lub tam jest znaną klasą SQL że katastrofie parsera (nie jestem nawet pewien, dlaczego ADO będzie analizować oświadczenia zamiast tylko przejazdem to t do bazy danych).
Oto kod VBA w całości do wersji, która wywala:
Option Explicit
Sub Go()
Dim lConn As ADODB.Connection
Dim lRecordset As ADODB.Recordset
'Dim lRecordset
Dim sSQL As String
Set lConn = New ADODB.Connection
Set lRecordset = New ADODB.Recordset
'Set lRecordset = CreateObject("ADODB.Recordset")
lConn.Open "Provider=MSDAORA;Data Source=(DESCRIPTION=(CID=GTU_APP)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=devdb)(PORT=1521)))(CONNECT_DATA=(SID=oracle)(SERVER=DEDICATED)));User Id=csuk;Password=thisisnotmyrealpassword;"
With lRecordset
sSQL = "select * " & _
"from(select * " & _
" from (select 1 id, 100 val from dual " & _
" Union all " & _
" select 2 id, 200 val from dual) " & _
" model return updated rows " & _
" dimension by(id) " & _
" measures (val) " & _
" rules (val[1] = val[cv()]+1)) " & _
"where val=101"
.Open sSQL, lConn
While Not .EOF
Sheets(1).Cells(1, 1) = ![Val]
.MoveNext
Wend
.Close
End With
Set lRecordset = Nothing
lConn.Close
Set lConn = Nothing
End Sub
W odpowiedzi na komentarz, próbowałem tego samego SQL przy użyciu DAO, a do mojej konsternacji, my uzyskać ten sam wynik. Poniższy kod awarii Excel, ale usunięcie return updated rows
jest potrzebny, aby działać zgodnie z oczekiwaniami:
Option Explicit
Sub Go()
Dim lWorkspace As DAO.Workspace
Dim lDatabase As DAO.Database
Dim lRecordset As DAO.Recordset
Dim sSQL As String
sSQL = "select * " & _
"from(select * " & _
" from (select 1 id, 100 val from dual " & _
" Union all " & _
" select 2 id, 200 val from dual) " & _
" model return updated rows " & _
" dimension by(id) " & _
" measures (val) " & _
" rules (val[1] = val[cv()]+1)) " & _
"where val=101"
Set lWorkspace = DBEngine.Workspaces(0)
Set lDatabase = lWorkspace.OpenDatabase("", False, False, "Driver={Microsoft ODBC for Oracle};Server=devdb:1521/oracle;Uid=charts_csuk_uksoft;Pwd=thisisnotmyrealpassword;")
Set lRecordset = lDatabase.OpenRecordset(sSQL, dbOpenDynaset, dbSQLPassThrough)
With lRecordset
While Not .EOF
Sheets(1).Cells(1, 1) = ![Val]
.MoveNext
Wend
End With
Set lRecordset = Nothing
Set lDatabase = Nothing
Set lWorkspace = Nothing
End Sub
add 'Set lConn = Nothing' poniżej' lConn.Close' aby uwolnić połączenie z połączeniem. Czy program Excel ulega awarii z późnym wiązaniem zestawu ADODB.Recordset? Zobacz także [tip] (http://www.vbforums.com/showthread.php?511763-Classic-VB-Dlaczego- nie----)-Dim-As-New-quot) odnoszące się do używania 'As Nowy ". Co powiesz na używanie alternatyw ADODB? Daj nam znać, jeśli któraś z nich pomoże –
Dzięki, próbowałem dodać 'set lConn = Nothing' i zaktualizowałem pytanie o tę poprawkę. Próbowałem również późnego wiązania (zobacz skomentowane wiersze w edytowanym pytaniu, żadne z nich nie zapobiegnie awarii, chciałbym wiedzieć, jakie alternatywy ADODB chciałbyś zasugerować? –
Pierwszym, o którym mogę pomyśleć, jest [DAO] (http://allenbrowne.com/ser-29.html) .Inną opcją byłoby napisanie własnej biblioteki COM przy użyciu C# lub VB.NET i dodanie odniesień do 'dll' (tak samo jak dodanie innych referencji, np. Microsoft Scripting Biblioteka) .Korzystanie z biblioteki COM pozwala na tworzenie własnych obiektów własnego typu w programie Excel Powiedział, że umożliwiłoby to przekazywanie kwerend bezpośrednio do biblioteki COM, która wykonywałaby go w bazie danych pomijając parser ADODB itp. użyj 'SQL Connection' z biblioteki' System.Data.SqlClient'. –