我使用以下在 ODBC 中准备和绑定的语句:
SELECT (CASE profile WHEN ? THEN 1 ELSE 2 END) AS profile_order
FROM engine_properties;
在与 AL32UTF8 字符集的 Oracle 10g 数据库的 ODBC 3.0 连接中执行,即使在使用 绑定到 wchar_t 字符串后SQLBindParameter(SQL_C_WCHAR)
,它仍然会给出错误 ORA-12704: character set mismatch。
为什么?我绑定为 wchar。不应该将 wchar 视为 NCHAR 吗?
如果我更改参数以包装它,TO_NCHAR()
那么查询将正常工作。但是,由于这些查询用于多个数据库后端,我不想只在 Oracle 文本绑定上添加 TO_NCHAR。有什么我想念的吗?在没有 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> 描述引擎属性; 名称空?类型 ----------------------------------------- -------- - -------------------------- EID 非空 NVARCHAR2(22) LID 非空数字 (11) 配置文件不为空 NVARCHAR2(32) PKEY 非空 NVARCHAR2(50) 值非空 NVARCHAR2(64) 只读非空数字(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