![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
|
[Paul Vero on the ODBC forum suggested I re-post this problem here] Using SQL Anywhere 11.0.1 and the ODBC driver (11.0.0.01.2331) running on Windows XP, the code I use to determine the column names of a table fails. The code basically does: SQLColumns(...) SQLBindCol(hStmt, 5, SQL_C_SSHORT, &nType, sizeof(int), &intLength); SQLBindCol(hStmt, 4, SQL_C_WCHAR, szColumnName, 25, &cbColumnName); The first bind (to column 5==DATA_TYPE) succeeds but the bind to column 4 (COLUMN_NAME) fails with: HY090: "[Sybase][ODBC Driver]Invalid string or buffer length" This code runs fine with several other ODBC drivers (SQLServer/Excel/txt driver/Oracle). I've attached a modified version of odbcconnect.cpp to demonstrate the issue. Any ideas what's going wrong? |
#2
| |||
| |||
|
|
Given the error message, my first guess is that the column is >25 bytes long. You appear to be using the Customers table from the SQL Anywhere 11 demo database. The 4th column of that table is the Street column which is a char(30). What happens if you increase the buffer length to 31 bytes? Robert Waywell | Practice Manager | Sybase iAnywhere | 519.883.6226 | rwaywell (AT) sybase (DOT) com | www.sybase.com [SQL Anywhere ODBC] HY090 error on trying to get column names> wrote in message news:4b1d005c.3c6e.1681692777 (AT) sybase (DOT) com... [Paul Vero on the ODBC forum suggested I re-post this problem here] Using SQL Anywhere 11.0.1 and the ODBC driver (11.0.0.01.2331) running on Windows XP, the code I use to determine the column names of a table fails. The code basically does: SQLColumns(...) SQLBindCol(hStmt, 5, SQL_C_SSHORT, &nType, sizeof(int), &intLength); SQLBindCol(hStmt, 4, SQL_C_WCHAR, szColumnName, 25, &cbColumnName); The first bind (to column 5==DATA_TYPE) succeeds but the bind to column 4 (COLUMN_NAME) fails with: HY090: "[Sybase][ODBC Driver]Invalid string or buffer length" This code runs fine with several other ODBC drivers (SQLServer/Excel/txt driver/Oracle). I've attached a modified version of odbcconnect.cpp to demonstrate the issue. Any ideas what's going wrong? |
#3
| |||
| |||
|
|
BufferLength is in bytes. But you are asking for WCHAR lengths which should be even numbers always (either way). If they are not even you get into odd truncation scenarios ... As it is you cannot save/fetch more than 12 characters (and not even that in some cases) with a buffer length of 25 which doesn't even come close to our 128 character identifiers (if that is being used). When I mock this up in ODBC Test I get the error if that length is odd, and not when even. Kind of makes sense though not necessarily consistent with the documentation for that SQLSTATE error. So that seems to be the source of this behaviour, whether it is acceptable standard behaviour or not is still an open question. "Rob Waywell" <rwaywell_no_spam (AT) sybase (DOT) com> wrote in message news:4b294307$1 (AT) forums-1-dub (DOT) .. Given the error message, my first guess is that the column is >25 bytes long. You appear to be using the Customers table from the SQL Anywhere 11 demo database. The 4th column of that table is the Street column which is a char(30). What happens if you increase the buffer length to 31 bytes? Robert Waywell | Practice Manager | Sybase iAnywhere | 519.883.6226 | rwaywell (AT) sybase (DOT) com | www.sybase.com [SQL Anywhere ODBC] HY090 error on trying to get column names> wrote in message news:4b1d005c.3c6e.1681692777 (AT) sybase (DOT) com... >> [Paul Vero on the ODBC forum suggested I re-post this >> problem here] Using SQL Anywhere 11.0.1 and the ODBC driver (11.0.0.01.2331) running on Windows XP, the code I use to >> determine the column names of a table fails. The code basically does: SQLColumns(...) SQLBindCol(hStmt, 5, SQL_C_SSHORT, &nType, sizeof(int), &intLength); SQLBindCol(hStmt, 4, SQL_C_WCHAR, szColumnName, 25, &cbColumnName); The first bind (to column 5==DATA_TYPE) succeeds but the >> bind to column 4 (COLUMN_NAME) fails with: HY090: "[Sybase][ODBC Driver]Invalid string or buffer length" This code runs fine with several other ODBC drivers (SQLServer/Excel/txt driver/Oracle). I've attached a modified version of odbcconnect.cpp to demonstrate the issue. Any ideas what's going wrong? |
#4
| |||
| |||
|
|
Thank you very much for pointing out the even/odd issue! Switching to even lengths was indeed what fixed the problem. SQLGetData shows the same behavior. I fixed my code and will move on, but in my humble opinion it would be better if the driver would return a value if it fits in the given number of bytes. When my app deals with different databases, each with their own column types (user defined types, and C mappings) truncation to a reasonable size is something that may happen and I can explain to my user. Perhaps I can find out what the different byte aligmnents/sizes are for all possible datatypes, although I haven't seen it in the few places I looked (SQLGetTypeInfo?). My life would be a bit easier if I would be able to specify a number of bytes, rather than the correct sizeof()... That's my 2cents, thanks very much for helping me fix this. BufferLength is in bytes. But you are asking for WCHAR lengths which should be even numbers always (either way). If they are not even you get into odd truncation scenarios ... As it is you cannot save/fetch more than 12 characters (and not even that in some cases) with a buffer length of 25 which doesn't even come close to our 128 character identifiers (if that is being used). When I mock this up in ODBC Test I get the error if that length is odd, and not when even. Kind of makes sense though not necessarily consistent with the documentation for that SQLSTATE error. So that seems to be the source of this behaviour, whether it is acceptable standard behaviour or not is still an open question. "Rob Waywell" <rwaywell_no_spam (AT) sybase (DOT) com> wrote in message news:4b294307$1 (AT) forums-1-dub (DOT) .. Given the error message, my first guess is that the column is >25 bytes long. You appear to be using the Customers table from the SQL Anywhere 11 demo database. The 4th column of that table is the Street column which is a char(30). What happens if you increase the buffer length to 31 bytes? Robert Waywell | Practice Manager | Sybase iAnywhere | 519.883.6226 | rwaywell (AT) sybase (DOT) com | www.sybase.com [SQL Anywhere ODBC] HY090 error on trying to get column names> wrote in message news:4b1d005c.3c6e.1681692777 (AT) sybase (DOT) com... >> [Paul Vero on the ODBC forum suggested I re-post this >> problem here] Using SQL Anywhere 11.0.1 and the ODBC driver (11.0.0.01.2331) running on Windows XP, the code I use to >> determine the column names of a table fails. The code basically does: SQLColumns(...) SQLBindCol(hStmt, 5, SQL_C_SSHORT, &nType, sizeof(int), &intLength); SQLBindCol(hStmt, 4, SQL_C_WCHAR, szColumnName, 25, &cbColumnName); The first bind (to column 5==DATA_TYPE) succeeds but the >> bind to column 4 (COLUMN_NAME) fails with: HY090: "[Sybase][ODBC Driver]Invalid string or buffer length" This code runs fine with several other ODBC drivers (SQLServer/Excel/txt driver/Oracle). I've attached a modified version of odbcconnect.cpp to demonstrate the issue. Any ideas what's going wrong? |
![]() |
| Thread Tools | |
| Display Modes | |
| |