-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Situation
If the filed is type NVARCHAT, and we use RecordSet to visit the selected result, we can only get half of what we want.
Root cause
There is a bug in the prepareVariableLen method, which we use to bind the column buffer.
Solution
- Wrong DataType specified.
Modify the following method from
inline void Preparator::prepare(std::size_t pos, const UTF16String&)
{
prepareVariableLenUTF16String::value_type(pos, SQL_C_WCHAR, maxDataSize(pos), DT_CHAR);
}
to
inline void Preparator::prepare(std::size_t pos, const UTF16String&)
{
prepareVariableLenUTF16String::value_type(pos, SQL_C_WCHAR, maxDataSize(pos), DT_WCHAR);
}
2. Wrong size specified for column binding buffer. Modify following method from template void prepareVariableLen(std::size_t pos, SQLSMALLINT valueType, std::size_t size, DataType dt) /// Utility function for preparation of variable length columns. { poco_assert (DE_BOUND == _dataExtraction); poco_assert (pos < _values.size());
T* pCache = new T[size];
std::memset(pCache, 0, size);
_values[pos] = Any(pCache);
_lengths[pos] = (SQLLEN) size;
_varLengthArrays.insert(IndexMap::value_type(pos, dt));
if (Utility::isError(SQLBindCol(_rStmt,
(SQLUSMALLINT) pos + 1,
valueType,
(SQLPOINTER) pCache,
(SQLINTEGER) size,
&_lengths[pos])))
{
throw StatementException(_rStmt, "SQLBindCol()");
}
}
to
template
void prepareVariableLen(std::size_t pos, SQLSMALLINT valueType, std::size_t size, DataType dt)
/// Utility function for preparation of variable length columns.
{
poco_assert (DE_BOUND == _dataExtraction);
poco_assert (pos < _values.size());
T* pCache = new T[size];
std::memset(pCache, 0, size);
_values[pos] = Any(pCache);
_lengths[pos] = (SQLLEN) size;
_varLengthArrays.insert(IndexMap::value_type(pos, dt));
if (Utility::isError(SQLBindCol(_rStmt,
(SQLUSMALLINT) pos + 1,
valueType,
(SQLPOINTER) pCache,
(SQLINTEGER) size * sizeof(T), // Here is the difference. Please help check if this is enough to work correctly.
&_lengths[pos])))
{
throw StatementException(_rStmt, "SQLBindCol()");
}
}
Personally, I need to save Unicode text in my database. And I'd like to use RecordSet to get whatever I want casually. So these functions are very much needed.
Since I have not got the whole view for this problem, maybe I even can't, so please help check this.
Thanks a lot.