Я использую следующее утверждение, подготовленное и связанное в ODBC:
SELECT (CASE profile WHEN ? THEN 1 ELSE 2 END) AS profile_order
FROM engine_properties;
Выполняется при подключении ODBC 3.0 к базе данных Oracle 10g в кодировке AL32UTF8, даже после привязки к строке wchar_t с использованием SQLBindParameter(SQL_C_WCHAR)
все равно выдает ошибку ORA-12704: несоответствие набора символов.
Почему? Я обязываю как wchar. Разве wchar не должен считаться NCHAR?
Если я изменяю параметр, чтобы обернуть его с помощью TO_NCHAR()
, тогда запрос работает без ошибок. Однако, поскольку эти запросы используются для нескольких баз данных, я не хочу добавлять TO_NCHAR только для текстовых привязок Oracle. Есть что-то, чего мне не хватает? Еще один способ решить эту проблему без молотка TO_NCHAR?
Мне не удалось найти что-либо релевантное с помощью поисков или руководств.
Подробнее ...
- ошибка
SELECT (CASE profile WHEN '_default' THEN 1 ELSE 2 END) AS profile_order
FROM engine_properties;
- хорошо
SELECT (CASE profile WHEN TO_NCHAR('_default') THEN 1 ELSE 2 END) AS profile_order
FROM engine_properties;
SQL> describe engine_properties;
Name Null? Type
----------------------------------------- -------- ----------------------------
EID NOT NULL NVARCHAR2(22)
LID NOT NULL NUMBER(11)
PROFILE NOT NULL NVARCHAR2(32)
PKEY NOT NULL NVARCHAR2(50)
VALUE NOT NULL NVARCHAR2(64)
READONLY NOT NULL NUMBER(5)
Эта версия без TO_NCHAR прекрасно работает в SQL Server и PostgreSQL (через ODBC) и SQLite (прямой). Однако в Oracle он возвращает «ORA-12704: несоответствие набора символов».
SQLPrepare(SELECT (CASE profile WHEN ? THEN 1 ELSE 2 END) AS profile_order
FROM engine_properties;) = SQL_SUCCESS
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_WCHAR,
SQL_VARCHAR, 32, 0, "_default", 18, 16) = SQL_SUCCESS
SQLExecute() = SQL_ERROR
SQLGetDiagRec(1) = SQL_SUCCESS
[SQLSTATE: HY000, NATIVE: 12704, MESSAGE: [Oracle][ODBC]
[Ora]ORA-12704: character set mismatch]
SQLGetDiagRec(2) = SQL_NO_DATA
Если я использую TO_NCHAR, все нормально (но не будет работать в SQL Server, Postgres, SQLite и т. Д.).
SQLPrepare(SELECT (CASE profile WHEN TO_NCHAR(?) THEN 1 ELSE 2 END) AS profile_order
FROM engine_properties;) = SQL_SUCCESS
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_WCHAR,
SQL_VARCHAR, 32, 0, "_default", 18, 16) = SQL_SUCCESS
SQLExecute() = SQL_SUCCESS
SQLNumResultCols() = SQL_SUCCESS (count = 1)
SQLFetch() = SQL_SUCCESS