The two statements are similar, but in the second case, each time it is executed, a failure occurs. The only difference between model and model return updated rows (I specifically designed this minimal example so that the queries return exactly the same data anyway, my real SQL, of course, is different):
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
Whether this is an isolated example of an error in ADO or there is a well-known class of SQL statements that break the parser (I'm not even sure why ADO will parse the statement and not just pass it to the database).
Here's the full VBA code for the version that crashes:
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
In response to the comment, I tried the same SQL using DAO, and to my surprise, we get the same result. The following code crashes Excel, but removing return updated rows is all it takes to get it working as expected:
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
user533832
source share