in src/main/cpp/odbcappender.cpp [412:516]
void ODBCAppender::ODBCAppenderPriv::setPreparedStatement(SQLHDBC con, Pool& p)
{
auto ret = SQLAllocHandle( SQL_HANDLE_STMT, con, &this->preparedStatement);
if (ret < 0)
{
throw SQLException( SQL_HANDLE_DBC, con, "Failed to allocate statement handle.", p);
}
#if LOG4CXX_LOGCHAR_IS_WCHAR
ret = SQLPrepareW(this->preparedStatement, (SQLWCHAR*)this->sqlStatement.c_str(), SQL_NTS);
#elif LOG4CXX_LOGCHAR_IS_UTF8
ret = SQLPrepareA(this->preparedStatement, (SQLCHAR*)this->sqlStatement.c_str(), SQL_NTS);
#else
SQLWCHAR* wsql;
encode(&wsql, this->sqlStatement, p);
ret = SQLPrepareW(this->preparedStatement, wsql, SQL_NTS);
#endif
if (ret < 0)
{
throw SQLException(SQL_HANDLE_STMT, this->preparedStatement, "Failed to prepare sql statement.", p);
}
int parameterNumber = 0;
for (auto& item : this->parameterValue)
{
++parameterNumber;
SQLSMALLINT targetType;
SQLULEN targetMaxCharCount;
SQLSMALLINT decimalDigits;
SQLSMALLINT nullable;
auto ret = SQLDescribeParam
( this->preparedStatement
, parameterNumber
, &targetType
, &targetMaxCharCount
, &decimalDigits
, &nullable
);
if (ret < 0)
{
throw SQLException(SQL_HANDLE_STMT, this->preparedStatement, "Failed to describe parameter", p);
}
if (SQL_CHAR == targetType || SQL_VARCHAR == targetType || SQL_LONGVARCHAR == targetType)
{
item.paramType = SQL_C_CHAR;
item.paramMaxCharCount = targetMaxCharCount;
item.paramValueSize = (SQLINTEGER)(item.paramMaxCharCount) * sizeof(char) + sizeof(char);
item.paramValue = (SQLPOINTER)p.palloc(item.paramValueSize + sizeof(char));
}
else if (SQL_WCHAR == targetType || SQL_WVARCHAR == targetType || SQL_WLONGVARCHAR == targetType)
{
item.paramType = SQL_C_WCHAR;
item.paramMaxCharCount = targetMaxCharCount;
item.paramValueSize = (SQLINTEGER)(targetMaxCharCount) * sizeof(wchar_t) + sizeof(wchar_t);
item.paramValue = (SQLPOINTER)p.palloc(item.paramValueSize + sizeof(wchar_t));
}
else if (SQL_TYPE_TIMESTAMP == targetType || SQL_TYPE_DATE == targetType || SQL_TYPE_TIME == targetType
|| SQL_DATETIME == targetType)
{
item.paramType = SQL_C_TYPE_TIMESTAMP;
item.paramMaxCharCount = (0 <= decimalDigits) ? decimalDigits : 6;
item.paramValueSize = sizeof(SQL_TIMESTAMP_STRUCT);
item.paramValue = (SQLPOINTER)p.palloc(item.paramValueSize);
}
else
{
if (SQL_INTEGER != targetType)
{
LogString msg(LOG4CXX_STR("Unexpected targetType ("));
helpers::StringHelper::toString(targetType, p, msg);
msg += LOG4CXX_STR(") at parameter ");
helpers::StringHelper::toString(parameterNumber, p, msg);
msg += LOG4CXX_STR(" while preparing SQL");
LogLog::warn(msg);
}
item.paramMaxCharCount = 30;
#if LOG4CXX_LOGCHAR_IS_UTF8
item.paramType = SQL_C_CHAR;
item.paramValueSize = (SQLINTEGER)(item.paramMaxCharCount) * sizeof(char);
item.paramValue = (SQLPOINTER)p.palloc(item.paramValueSize + sizeof(char));
#else
item.paramType = SQL_C_WCHAR;
item.paramValueSize = (SQLINTEGER)(item.paramMaxCharCount) * sizeof(wchar_t);
item.paramValue = (SQLPOINTER)p.palloc(item.paramValueSize + sizeof(wchar_t));
#endif
}
item.strLen_or_Ind = SQL_NTS;
ret = SQLBindParameter
( this->preparedStatement
, parameterNumber
, SQL_PARAM_INPUT
, item.paramType // ValueType
, targetType
, targetMaxCharCount
, decimalDigits
, item.paramValue
, item.paramValueSize
, &item.strLen_or_Ind
);
if (ret < 0)
{
throw SQLException(SQL_HANDLE_STMT, this->preparedStatement, "Failed to bind parameter", p);
}
}
}