[Mono-dev] Odbc and varchar - patch for varchars longer than 255
Mads Bondo Dydensborg
mbd at dbc.dk
Tue Jun 19 06:23:32 EDT 2007
Hi there.
I have had problems with strings containing binary 0, when retrieved through
the mono stack. Looking at OdbcDataReader, there seems to be a difference
between how GetBytes and GetValue( "varchar" ) works.
GetBytes has this:
10 if (copyBuffer) {
311 int i = 0;
312 while (tbuff [i] != libodbc.C_NULL) {
313 buffer [bufferIndex + i] =
tbuff [i];
314 i++;
315 }
316 returnVal = i;
317 }
318 return returnVal;
31
Whereas GetValue has this (sorry about the formatting):
696 case OdbcType.VarChar:
697 bufsize = (col.MaxLength <
255 ? (col.MaxLength+1) : 255);
698 buffer = new
byte[bufsize]; // According to sqlext.h, use SQL_CHAR for both char and
varchar
699 StringBuilder sb1 = new
StringBuilder ();
700 do {
701 ret =
libodbc.SQLGetData (hstmt, ColIndex, col.SqlCType, buffer, bufsize, ref
outsize);
702 if (ret ==
OdbcReturn.Error)
703 break;
704 if (ret !=
OdbcReturn.NoData && outsize!=-1) {
705 if (outsize <
bufsize)
706
sb1.Append (System.Text.Encoding.Default.GetString(buffer,0,outsize));
707 else
708
sb1.Append (System.Text.Encoding.Default.GetString(buffer,0,bufsize));
709 }
710 } while (ret !=
OdbcReturn.NoData);
711 DataValue = sb1.ToString ();
712 break;
According to
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcsqlgetdata.asp
"It is up to the application to reassemble the parts, taking care to remove
the null-termination character from intermediate parts of character data. "
This patch fixes my problem:
Index: OdbcDataReader.cs
===================================================================
--- OdbcDataReader.cs (revision 80063)
+++ OdbcDataReader.cs (working copy)
@@ -705,7 +705,7 @@
if (outsize < bufsize)
sb1.Append
(System.Text.Encoding.Default.GetString(buffer,0,outsize));
else
- sb1.Append
(System.Text.Encoding.Default.GetString(buffer,0,bufsize));
+ sb1.Append
(System.Text.Encoding.Default.GetString(buffer,0,bufsize-1));
}
} while (ret != OdbcReturn.NoData);
DataValue = sb1.ToString ();
It assumes any fragment, with more data, always contains a binary zero on the
last position. This may or may not be the case - some Odbc expert should
probably look at it. There could be a problem with NVarchar also.
Regards,
Mads
--
Med venlig hilsen/Regards
Systemudvikler/Systemsdeveloper cand.scient.dat, Ph.d., Mads Bondo Dydensborg
Dansk BiblioteksCenter A/S, Tempovej 7-11, 2750 Ballerup, Tlf. +45 44 86 77 34
More information about the Mono-devel-list
mailing list