PrepareStatement issue with more than 255 characters in libodbc++-0.2.4pre4
Hi,
I have statically linked libodbc++ library (libodbc++-mt.a) with my C++ application to store/retrieve data from MySQL.
Previously, when I was using libodbc++-0.2.3, database inserts (using preparestatement) works well even for strings with morethan 255 characters.
I upgraded to libodbc++-0.2.4pre4 and when I do inserts with morethan 255 characters, the string is truncated to 255 characters and then inserted into the database.
Im using unixODBC 2.2.15pre and libmyodbc v3.51.27.
Am I missing anything. Can anyone help me on this.
I have also tried in libodbc++ mailing list and I didnt get any response.
Regards,
Srini
Re: PrepareStatement issue with more than 255 characters in libodbc++-0.2.4pre4
Quote:
Originally Posted by
srinivasant
I upgraded to libodbc++-0.2.4pre4 and when I do inserts with morethan 255 characters, the string is truncated to 255 characters and then inserted into the database.
1) Doing a web search for that library, that library comes with full source code. If it's the same library that you're using, why don't you debug it?
2) Making ODBC calls is easy without using any library.
3) As to ODBC itself, if you bind variables to the columns before you retrieve them, you are limited to the binding variable's size. So if it's character data and you bind a character buffer to the column, when the column is retrieved, the data will be truncated to the size of the buffer.
So unless the library or the ODBC driver itself has a bug, if libodbc is binding the output column data before retrieving the data from the returned result set, then ODBC is behaving exactly as documented (you are limiting the data to the size of the buffer). If that buffer has 255, then you will only get 255 characters.
To override this, you have to retrieve the data first (SQLFetch), and then get the column's actual data length (SQLGetData). It is in there you get the actual data's size. Then you call SQLGetData() one more time to retrieve the actual contents.
The above is how you would do it if you were using straight ODBC. Since you are not, you have to debug the library's sources. Again, ODBC is behaving exactly as documented if the data is retrieved by having the column data bound to variables before the result set is retrieved (using SQLFetch).
This is why knowing something about the underlying way ODBC works, even if you're using a library, is advantageous.
Quote:
Am I missing anything. Can anyone help me on this.
The thing your "missing" is to learn how basic ODBC works.
Quote:
I have also tried in libodbc++ mailing list and I didnt get any response.
Again, that library comes with full source code. Nothing stops you from looking at the code to see which approach is done (binding variables or not binding variables) to retrieve column data.
Regards,
Paul McKenzie
Re: PrepareStatement issue with more than 255 characters in libodbc++-0.2.4pre4
Hi Paul,
Thanks for your response and valuable suggestions.
The problem occurs only when I do inserts to the database and not during database read (select).
I have tried debugging the libodbc++ source code. In the latest v0.2.4pre4,
in datahandler.cpp, in method DataHandler::setString() I could see a code like this,
if(!isStreamed_) {
unsigned int len=(unsigned int)ODBCXX_STRING_LEN(str);
if((len+1)*sizeof(ODBCXX_CHAR_TYPE)>bufferSize_) {
len=(bufferSize_-1)/sizeof(ODBCXX_CHAR_TYPE);
}
if the length of str is greater than 256, then it set to 255. The sizeof(ODBCXX_CHAR_TYPE) is 1. This piece of code is not available in the previous version.
The bufferSize_ is the precision which is set as follows in datahander.h
switch(sqlType) {
case Types::CHAR:
case Types::VARCHAR:
case Types::BINARY:
case Types::VARBINARY:
prec=255;
I am just trying to fix this in libodbc code by myself and will do some testing. Will update you.
Thanks & Regards,
Srini
Re: PrepareStatement issue with more than 255 characters in libodbc++-0.2.4pre4
Quote:
Originally Posted by
srinivasant
Hi Paul,
Thanks for your response and valuable suggestions.
The problem occurs only when I do inserts to the database and not during database read (select).
I have tried debugging the libodbc++ source code. In the latest v0.2.4pre4,
in datahandler.cpp, in method DataHandler::setString() I could see a code like this,
if(!isStreamed_) {
unsigned int len=(unsigned int)ODBCXX_STRING_LEN(str);
if((len+1)*sizeof(ODBCXX_CHAR_TYPE)>bufferSize_) {
len=(bufferSize_-1)/sizeof(ODBCXX_CHAR_TYPE);
}
if the length of str is greater than 256, then it set to 255. The sizeof(ODBCXX_CHAR_TYPE) is 1. This piece of code is not available in the previous version.
The bufferSize_ is the precision which is set as follows in datahander.h
switch(sqlType) {
case Types::CHAR:
case Types::VARCHAR:
case Types::BINARY:
case Types::VARBINARY:
prec=255;
I am just trying to fix this in libodbc code by myself and will do some testing. Will update you.
Thanks & Regards,
Srini
Before fixing the code, you need to see the general approach that library retrieves column data.
If the library binds variables first using SQLBind and then retrieves data using SQLFetch(), then you're out of luck. No fix is possible, since that is how ODBC is designed. Unless you're willing to rip the guts out of the library and start over building your own code base, you have to stay with this approach.
If on the other hand, the library doesn't bind variables, but instead calls SQLFetch() and then SQLGetData(), then you have a shot in fixing the code, since this is the way to retrieve all of the data you are seeking.
So you have to make the determination -- does that library bind variables or does it not bind variables to retrieve the data?
Regards,
Paul McKenzie
Re: PrepareStatement issue with more than 255 characters in libodbc++-0.2.4pre4
Paul,
Thanks for the inputs,
Actually the lib bind the values using SQLBindParameter() call.
But never mind, one of my friend had fixed this issue earlier in older version. I reviewed his code and integrated his changes to my latest lib version and it works well now.
Thanks for all your suggestions and help.
Regards,
Srini