Open matthew-wozniczka opened 3 years ago
The same thing happens if BufferLength is set exactly to the length of the string in bytes (not including the null terminator).
In this case, we're setting the length indicator to SQL_NTS, and the buffer actually contains a length indicator, but I'm not sure if this is 'correct' (since technically the null terminator is outside of the buffer as described to the DM/Driver), but again, it used to work.
As indicated by @pkleef this issue has been assigned for fixing. Thus, expect a fix later today or tomorrow.
@matthew-wozniczka
The same thing happens if BufferLength is set exactly to the length of the string in bytes (not including the null terminator).
In this case, we're setting the length indicator to SQL_NTS, and the buffer actually contains a length indicator, but I'm not sure if this is 'correct' (since technically the null terminator is outside of the buffer as described to the DM/Driver), but again, it used to work.
It is unclear, why BufferLength isn't include null terminator => https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbindparameter-function?view=sql-server-ver15#bufferlength-argument
For character C data, if the number of bytes available to return is greater than or equal to BufferLength,
the data in *ParameterValuePtr is truncated to BufferLength less the length of a null-termination character
and is null-terminated by the driver.
that passage is about output parameters:
For input/output and output parameters, it is used to determine whether to truncate character and binary C data on output
@matthew-wozniczka Did you use one row binding or Array parameters binding ?
In this case I'm not using parameter arrays (having a bufferlength of 0 definitely would not work there)
@matthew-wozniczka About call
SQLRETURN SQLBindParameter(
SQLHSTMT StatementHandle,
SQLUSMALLINT ParameterNumber,
SQLSMALLINT InputOutputType,
SQLSMALLINT ValueType,
SQLSMALLINT ParameterType,
SQLULEN ColumnSize,
SQLSMALLINT DecimalDigits,
SQLPOINTER ParameterValuePtr,
SQLLEN BufferLength,
SQLLEN * StrLen_or_IndPtr);
What kind of value did you use for ColumnSize
in your code (for example) ?
Is it equal max value len in parameter ?
What kind of ODBC driver did you use Unicode or ANSI ? Does it support UCS4 codepage ?
Fixed.
The issue, when BufferLength == 0
was fixed,
ColumnSize
parameter has propely value !=0 About:
The same thing happens if BufferLength is set exactly to the length of the string in bytes (not including the null terminator).
In this case, we're setting the length indicator to SQL_NTS, and the buffer actually contains a length indicator, but I'm not sure if this is 'correct' (since technically the null terminator is outside of the buffer as described to the DM/Driver), but again, it used to work.
It will work ONLY, if Unicode conversion isn't used(Unicode->Ansi or UCS4->UCS2 and etc), but it is better not use such calls, I think.
I'm not sure if passing a bufferlength of 0 to SQLBindParameter for a string parameter while using a length indicator of SQL_NTS is completely kosher, but it used to work (circa 3.52.8, and in other DMs).
I find that the DM seems to try to support it, in
_SQLExecute_ConvParams
it computeselementSize
to be the size in bytes, without the null terminator, and then in_ConvParam
->_ExecConv_W2W
it copies the entire value back to the buffer, but then overwrites the last character with a null terminator.