Bug #29633 | DESCRIBE table only returns first field using ADO and Excel CopyFromRecordset | ||
---|---|---|---|
Submitted: | 8 Jul 2007 22:37 | Modified: | 15 Jul 2007 12:35 |
Reporter: | John Wilson | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | Connector / ODBC | Severity: | S2 (Serious) |
Version: | 5.00.11 | OS: | Windows (XP SP2) |
Assigned to: | CPU Architecture: | Any | |
Tags: | ADO, DESCRIBE, recordset, SHOW CREATE |
[8 Jul 2007 22:37]
John Wilson
[12 Jul 2007 19:38]
Tonci Grgin
Hi John and thanks for your report. I don't quite get it so I'll propose a thing or two: - Please concentrate on MyODBC 3.51.16 - Please provide ODBC trace log - Please give me instructions on how (and where) to put VB code in Excel - Have you considered http://msdn2.microsoft.com/en-us/library/aa223845(office.11).aspx? - How I see it, the code should be like this: Const DSN = "Driver={MySQL ODBC 3.51 Driver};Uid=root;Pwd=;Server=localhost;Database=test;OPTION=1 + 2 + 8 + 16384" Const adOpenForwardOnly = 0 Const adOpenKeyset = 1 Const adOpenDynamic = 2 Const adOpenStatic = 3 Const adOpenUnspecified = -1 Const adUseNone = 1 Const adUseServer = 2 Const adUseClient = 3 Const adLockReadOnly = 1 Const adLockPessimistic = 2 Const adLockOptimistic = 3 '---- ParameterDirectionEnum Values ---- Const adParamUnknown = &H0 Const adParamInput = &H1 Const adParamOutput = &H2 Const adParamInputOutput = &H3 Const adParamReturnValue = &H4 '---- CommandTypeEnum Values ---- Const adCmdUnknown = &H8 Const adCmdText = &H1 Const adCmdTable = &H2 Const adCmdStoredProc = &H4 Const adCmdFile = &H100 Const adCmdTableDirect = &H200 Const adInteger = 3 Const adDate = 7 Const adVarChar = 200 Dim cnxDatabase Dim strSQL Dim iCols ' connecting database Set cnxDatabase = CreateObject("ADODB.Connection") cnxDatabase.Open (DSN) 'WScript.Echo "Connected" cnxDatabase.Execute ("USE test") cnxDatabase.Execute ("DROP TABLE IF EXISTS bug29633") cnxDatabase.Execute ("CREATE TABLE `bug29633` (`f1` char(10) , `f2` char(10),`f3` decimal(3,1),`f4` decimal(3,1),`f5` char(10))") ' querying data strSQL = "DESCRIBE `bug29633`" Dim rs Set rs = CreateObject("ADODB.Recordset") With rs .ActiveConnection = cnxDatabase .CursorLocation = adUseClient .LockType = adLockOptimistic .CursorType = adOpenDynamic .Properties("Update Criteria").Value = 0 .Open (strSQL) End With For iCols = 0 To rs.Fields.Count - 1 ws.Cells(1, iCols + 1).Value = rs.Fields(iCols).Name Next ws.Range(ws.Cells(1, 1), _ ws.Cells(1, rs.Fields.Count)).Font.Bold = True ws.Range("A2").CopyFromRecordset rs rs.Close cnxDatabase.Close Set rs = Nothing Set cnxDatabase = Nothing From what appears on the first look, Excel has problems reading the BLOB fields thus breaking on first one (Field 2: `Type`): C:\mysql507\bin>mysql -uroot -T test Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.0.44-max-nt-log Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> DESCRIBE bug29633; Field 1: `Field` Catalog: `def` Database: `` Table: `COLUMNS` Org_table: `` Type: VAR_STRING Collation: latin1_swedish_ci (8) Length: 64 Max_length: 2 Decimals: 0 Flags: NOT_NULL Field 2: `Type` Catalog: `def` Database: `` Table: `COLUMNS` Org_table: `` Type: BLOB Collation: latin1_swedish_ci (8) Length: 196605 Max_length: 12 Decimals: 0 Flags: NOT_NULL BLOB Field 3: `Null` Catalog: `def` Database: `` Table: `COLUMNS` Org_table: `` Type: VAR_STRING Collation: latin1_swedish_ci (8) Length: 3 Max_length: 3 Decimals: 0 Flags: NOT_NULL Field 4: `Key` Catalog: `def` Database: `` Table: `COLUMNS` Org_table: `` Type: VAR_STRING Collation: latin1_swedish_ci (8) Length: 3 Max_length: 0 Decimals: 0 Flags: NOT_NULL Field 5: `Default` Catalog: `def` Database: `` Table: `COLUMNS` Org_table: `` Type: BLOB Collation: latin1_swedish_ci (8) Length: 196605 Max_length: 0 Decimals: 0 Flags: BLOB Field 6: `Extra` Catalog: `def` Database: `` Table: `COLUMNS` Org_table: `` Type: VAR_STRING Collation: latin1_swedish_ci (8) Length: 20 Max_length: 0 Decimals: 0 Flags: NOT_NULL +-------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+-------+ | f1 | char(10) | YES | | NULL | | | f2 | char(10) | YES | | NULL | | | f3 | decimal(3,1) | YES | | NULL | | | f4 | decimal(3,1) | YES | | NULL | | | f5 | char(10) | YES | | NULL | | +-------+--------------+------+-----+---------+-------+ 5 rows in set (0.02 sec) mysql>
[13 Jul 2007 18:19]
John Wilson
> From what appears on the first look, Excel has problems reading the BLOB > fields thus breaking on first one (Field 2: `Type`): > Ah yes, I was aware that BLOB fields gave unexpected results in general but never looked into why, and hadn't realised DESCRIBE would involve BLOB fields until you pointed this out. Anyway, I used your suggested code to see if it produced the same result, and to my surprise your code returned the correct result set! :-) [BTW, your code was missing "Set ws = ActiveSheet"] The line which made all the difference was: rs.CursorLocation = adUseClient It turns out that the default for CursorLocation is adUseServer, and that BLOB fields "will fail or return abnormal results when used with a server-side cursor." http://dev.mysql.com/tech-resources/articles/vb-cursors-and-locks.html provides a very good overview of ADO cursor usage with MySQL. "...certain functionality, such as the RecordCount property of a Recordset and the GetChunk and Appendchunk function for handling BLOB data, will fail or return abnormal results when used with a server-side cursor." So, I can confirm that: DESCRIBE test_table; SHOW CREATE TABLE test_table; both work fine with the client side cursor setting. BTW, why does the adUseServer server side cursor setting not handle BLOB fields correctly? Will this be fixed in the future or is there something fundamental about the design of the ODBC stack that means a server side cursor (i.e. ODBC side cursor) cannot be made to handle data which contains BLOB fields correctly? BTW, even with adUseServer, ODBC driver 3.51.06 against a 4.1.6 database never had any problems with the queries: DESCRIBE test_table; SHOW CREATE TABLE test_table; Also, as a matter of interest: DESCRIBE test_table; works fine with 3.51.06 and 5.0.42 database (with adUseServer) although there are still other BLOB field issues with 3.51.06 (especially when used with a 5.0.42 database). > Please give me instructions on how (and where) to put VB code in Excel > Tools, Macro, Visual Basic Editor Thank you for the sample code without which I would never have realised the problem was due to the adUseServer default for CursorLocation.
[15 Jul 2007 12:35]
Tonci Grgin
John, I'm glad the problem is solved. Now we can discuss other questions leisurely :) > BTW, why does the adUseServer server side cursor setting not handle BLOB fields correctly? Will this be fixed in the future or is there something fundamental about the design of the ODBC stack that means a server side cursor (i.e. ODBC side cursor) cannot be made to handle data which contains BLOB fields correctly? We are aware of SS cursors problems for some time now and actively working on a solution. You'll find a lot of bug reports regarding this problem in bugs-db. I can't tell exactly when the solution will become available but it will be soon. > BTW, even with adUseServer, ODBC driver 3.51.06 against a 4.1.6 database never had any problems with the queries: DESCRIBE test_table; SHOW CREATE TABLE test_table; Also, as a matter of interest: DESCRIBE test_table; works fine with 3.51.06 and 5.0.42 database (with adUseServer) although there are still other BLOB field issues with 3.51.06 (especially when used with a 5.0.42 database). This is due to differences in the way of work between the versions. Ver.5 relies on I__S database to provide the info requested but that is whole another problem which you can catch a glimpse of in Bug#10491. That also represents the root cause of DESCRIBE table problems in latest versions of MyODBC 3.51 (from v. 14 up).