Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SA11: Strange behavior when accessing SQL Anywhere 11 using Microsoft OLE DB Provider for ODBC (MSDASQL)

7 views
Skip to first unread message

Andrei Iliev

unread,
Oct 6, 2008, 2:31:52 PM10/6/08
to
SA11 Strange behavior when accessing SQL Anywhere 11 using Microsoft
OLE DB Provider for ODBC (MSDASQL).

A simle select from a table or a table join returns inconsistence number
of rows using ADODB cursor type other then ForwarOnly

Step to reproduce:
1) Prepare table and data (create Tables in demo datebase 'SQL Anywhere
11 Demo')

=============================================
CREATE TABLE "DBA"."Msg" (
"id" INTEGER NOT NULL DEFAULT AUTOINCREMENT,
"Title" LONG VARCHAR NOT NULL,
PRIMARY KEY ( "id" ASC )
);
CREATE TABLE "DBA"."Section" (
"id" INTEGER NOT NULL DEFAULT AUTOINCREMENT,
"name" LONG VARCHAR NOT NULL,
PRIMARY KEY ( "id" ASC )
);

CREATE TABLE "DBA"."MsgSection" (
"id_msg" INTEGER NOT NULL,
"id_section" INTEGER NOT NULL,
"ordr" INTEGER NULL DEFAULT 0,
PRIMARY KEY ( "id_msg" ASC, "id_section" ASC )
);

ALTER TABLE "DBA"."MsgSection" ADD CONSTRAINT "Msg" FOREIGN KEY (
"id_msg" ASC ) REFERENCES "DBA"."Msg" ( "id" ) ON DELETE CASCADE;
ALTER TABLE "DBA"."MsgSection" ADD CONSTRAINT "Section" FOREIGN KEY (
"id_section" ASC ) REFERENCES "DBA"."Section" ( "id" ) ON DELETE CASCADE;


INSERT INTO "DBA"."Msg" ("id","Title") VALUES(DEFAULT,'Msg1');
INSERT INTO "DBA"."Msg" ("id","Title") VALUES(DEFAULT,'Msg2');
INSERT INTO "DBA"."Section" ("id","name") VALUES(DEFAULT,'section1');
INSERT INTO "DBA"."Section" ("id","name") VALUES(DEFAULT,'section2');
INSERT INTO "DBA"."MsgSection" ("id_msg","id_section","ordr")
VALUES(1,1,DEFAULT);

=============================================

2) Create test.vbs:
==================Start script===========
'---- CursorTypeEnum Values ----
Const adOpenForwardOnly = 0
Const adOpenKeyset = 1
Const adOpenDynamic = 2
Const adOpenStatic = 3

'---- LockTypeEnum Values ----
Const adLockReadOnly = 1
Const adLockPessimistic = 2
Const adLockOptimistic = 3
Const adLockBatchOptimistic = 4

'---- CursorLocationEnum Values ----
Const adUseServer = 2
Const adUseClient = 3

'---- CommandTypeEnum Values ----
Const adCmdUnknown = &H0008
Const adCmdText = &H0001
Const adCmdTable = &H0002
Const adCmdStoredProc = &H0004
Const adCmdFile = &H0100
Const adCmdTableDirect = &H0200

Dim sSql
sSql="SELECT Msg.id,MsgSection.ordr,Msg.title FROM Msg key join
MsgSection where MsgSection.id_section= 1 order by Msg.id desc"

WScript.Echo "test1"
call Test1(sSql)

WScript.Echo "test2"
call Test2(sSql)

WScript.Echo "test2_2"
call Test2_2(sSql)

WScript.Echo "test3"
call Test3(sSql)

WScript.Echo "test4"
call Test4(sSql)

sSql="SELECT Msg.id,Msg.title FROM Msg"

WScript.Echo "test1"
call Test1(sSql)

WScript.Echo "test2"
call Test2(sSql)

WScript.Echo "test2_2"
call Test2_2(sSql)

WScript.Echo "test3"
call Test3(sSql)

WScript.Echo "test4"
call Test4(sSql)

Sub Test1(sSql)
Dim oConn
Dim oRS
set oConn= CreateObject("ADODB.Connection")
oConn.Open "SQL Anywhere 11 Demo"


Set oRs = CreateObject("ADODB.RecordSet")
oRs.Open sSQL, oConn, adOpenStatic, adLockReadOnly

Do while not oRs.Eof
WScript.Echo "id='" & oRs.Fields.Item("id").value & "'"

oRs.MoveNext
Loop
End Sub

Sub Test2(sSql)
Dim oConn
Dim oRS
set oConn= CreateObject("ADODB.Connection")
oConn.Open "SQL Anywhere 11 Demo"


Set oRs = CreateObject("ADODB.RecordSet")
oRs.Open sSQL, oConn, adOpenStatic, adLockReadOnly

WScript.Echo "Found records " & oRs.RecordCount

Do while not oRs.Eof
WScript.Echo "id='" & oRs.Fields.Item("id").value & "'"

oRs.MoveNext
Loop
End Sub

Sub Test2_2(sSql)
Dim oConn
Dim oRS
set oConn= CreateObject("ADODB.Connection")
oConn.Open "SQL Anywhere 11 Demo"


Set oRs = CreateObject("ADODB.RecordSet")
oRs.Open sSQL, oConn, adOpenStatic, adLockReadOnly

WScript.Echo "Eof?" & oRs.Eof
WScript.Echo "Found records " & oRs.RecordCount

Do while not oRs.Eof
WScript.Echo "id='" & oRs.Fields.Item("id").value & "'"

oRs.MoveNext
Loop
End Sub

Sub Test3(sSql)
Dim oConn
Dim oRS
set oConn= CreateObject("ADODB.Connection")
oConn.Open "SQL Anywhere 11 Demo"


Set oRs = CreateObject("ADODB.RecordSet")
oRs.Open sSQL, oConn, adOpenForwardOnly, adLockReadOnly

Do while not oRs.Eof
WScript.Echo "id='" & oRs.Fields.Item("id").value & "'"

oRs.MoveNext
Loop

End Sub


Sub Test4(sSql)
Dim oConn
Dim oRS
set oConn= CreateObject("ADODB.Connection")
oConn.Open "SQL Anywhere 11 Demo"


Set oRs = CreateObject("ADODB.RecordSet")
oRs.Open sSQL, oConn, adOpenStatic, adLockReadOnly

Do while not oRs.Eof
WScript.Echo "id='" & oRs.Fields.Item("id").value & "'"

oRs.MoveNext
Loop

End Sub
==================end script===========
3) run cscript test.vbs


4) I see the results:
test1
id='1'
id='1'
test2
Found records 2
id='1'
test2_2
Eof?False
Found records 1
id='1'
id='1'
test3
id='1'
test4
id='1'
id='1'
test1
id='1'
id='1'
id='2'
test2
Found records 2
id='1'
id='2'
test2_2
Eof?False
Found records 2
id='1'
id='1'
id='2'
test3
id='1'
id='2'
test4
id='1'
id='1'
id='2'

Stephen Rice

unread,
Oct 6, 2008, 4:04:49 PM10/6/08
to
Best thing to do is to turn on ODBC tracing and see what the MS provider is
actually sending.
--
/steve
Stephen Rice, Sybase iAnywhere
Please reply only to the newsgroup

iAnywhere Developer Community : http://www.ianywhere.com/developer
iAnywhere Docs : http://www.ianywhere.com/developer/product_manuals
ASA Patches and EBFs : http://downloads.sybase.com/swd/base.do
-> Choose SQL Anywhere Studio
-> Set filter to "Display ALL platforms IN ALL MONTHS"

"Andrei Iliev" <xz...@mail.ru> wrote in message news:48ea5998@forums-1-dub...

Stephen Rice [Sybase]

unread,
Oct 8, 2008, 11:20:34 AM10/8/08
to
All the odbc trace shows is the calls to and the returns from the ODBC
driver that the ms layer is making

I did some quick poking through the trace and the MS driver is doing all
sorts of weird and wonderful things that make it very hard to follow. For
example, they appear to be fetching every row at least twice (it appears
they fetch the first row three times).

I tried the same things through dbisql and it works as expected.

Before we drive ourselves mad with this trace please check to make sure your
odbc setting are similar between your v9 and v11 datasource. There are a
bunch of settings that modify how our driver responds to certain odbc
requests (MS Applications being one of them).

Working on the assumption that something has changed in SQL Anywhere, you
need to compare the traces from a version that works with a version that
doesn't to see what has changed.

I suggest you just take a single test that fails in v11 and works in v9 (to
reduce the log size to the minimum) and take the odbc trace from each.
Compare them to see if the calls or return values differ. In theory they
will be virtually identical (e.g. the handle values/memory addresses will be
different but the order the calls are in and the values returned should be
similar)

Once we know where they diverge we can figure out what happened

--
/steve
Stephen Rice, Sybase iAnywhere
Please reply only to the newsgroup

iAnywhere Developer Community : http://www.ianywhere.com/developer
iAnywhere Docs : http://www.ianywhere.com/developer/product_manuals
ASA Patches and EBFs : http://downloads.sybase.com/swd/base.do
-> Choose SQL Anywhere Studio
-> Set filter to "Display ALL platforms IN ALL MONTHS"

"Andrei Iliev" <xz...@mail.ru> wrote in message news:48ea7467@forums-1-dub...
>I think, the problem is not in MS provider,because it works with any
> ODBC (it just use odbc API). Moreover it works ok with ASA 9 ( and
> used to work with older version of ASA - v5,6,7,8, 9).
>
> But Ok , I did turn on ODBC tracing. Results in attachment. I don't
> know how to use it.
>
> Stephen Rice пишет:

Andrei Iliev

unread,
Oct 8, 2008, 6:09:30 PM10/8/08
to
Stephen Rice [Sybase] пишет:

>
> I tried the same things through dbisql and it works as expected.

Yes, I forgot to mentioned it. I think the problem is in SQL Anywhere 11
ODBC driver

>
> Before we drive ourselves mad with this trace please check to make sure your
> odbc setting are similar between your v9 and v11 datasource. There are a
> bunch of settings that modify how our driver responds to certain odbc
> requests (MS Applications being one of them).

I always use default settings.

>
> Working on the assumption that something has changed in SQL Anywhere, you
> need to compare the traces from a version that works with a version that
> doesn't to see what has changed.
>
> I suggest you just take a single test that fails in v11 and works in v9 (to
> reduce the log size to the minimum) and take the odbc trace from each.
> Compare them to see if the calls or return values differ. In theory they
> will be virtually identical (e.g. the handle values/memory addresses will be
> different but the order the calls are in and the values returned should be
> similar)
>
> Once we know where they diverge we can figure out what happened
>

Ok. I prepared a simple test (see files in attachments)
1) Create sample DBs for ASA 9 and for SA 11. In both databases create
a sample table with just 2 columns and fill the table with 2 records:

CREATE TABLE "DBA"."Msg" (
"id" INTEGER NOT NULL DEFAULT AUTOINCREMENT,
"Title" LONG VARCHAR NOT NULL,

PRIMARY KEY ( "id" )
);


INSERT INTO "DBA"."Msg" ("Title") VALUES('Msg1');
INSERT INTO "DBA"."Msg" ("Title") VALUES('Msg2');

See cr.bat.

2) Create 2 DSN with default parameters (see odbc.reg):
test9 - ASA 9
test11 - SA11

3) Run test


You'll find that running a simple query SELECT * from MSG where id=1
returns:

1 record for ASA 9 (cscript test9.vbs),
but 2 records for SA11 (cscript test11.vbs)!

Another strange thing in v11. If I put a call to oRs.RecordCount (get
number of records)before checking for oRs.Eof , I'll get 2, if I put it
after checking oRs.Eof it returns 1


I attached odbc tracinng log for v9 (sql9.log) and v11 (sql11.log)


Hope, it helps.

test.zip
0 new messages