我使用以下语句编写并绑定在ODBC中:
SELECT (CASE profile WHEN ? THEN 1 ELSE 2 END) AS profile_order
FROM engine_properties;
在AL32UTF8字符集中与Oracle 10g数据库的ODBC 3.0连接中执行,即使在使用SQLBindParameter(SQL_C_WCHAR)
绑定到wchar_t字符串之后,仍然会出现错误ORA-12704:字符集不匹配。
为什么呢?我绑定为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> 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
答案 0 :(得分:0)
如果Oracle数据库字符集是AL32UTF8,为什么列定义为NVARCHAR2?这意味着您希望使用国家字符集编码的列(通常为AL16UTF16,但数据库可能不同)。除非您主要存储亚洲语言数据(或AL32UTF8中需要3个字节存储空间的其他数据),否则当数据库字符集支持Unicode时,在Oracle数据库中创建NVARCHAR2列的情况相对较少。
通常,使用数据库字符集(CHAR和VARCHAR2列)而不是尝试使用国家字符集(NCHAR和NVARCHAR2列)可以更好地服务,因为需要跳转的环路要少得多通过开发/配置方面的事情。由于您没有增加可以通过选择NVARCHAR2数据类型进行编码的字符集,我会打赌您对VARCHAR2数据类型更满意。
答案 1 :(得分:0)
感谢贾斯汀。
我不能说我完全理解如何在VARCHAR2和NVARCHAR2之间进行选择。我曾尝试将VARCHAR2用于我的约会(其中包括许多不同的语言,包括欧洲和亚洲),并且它在那段时间没有用。
我再次玩了一遍,我发现使用Justin的建议可以在这个组合中使用:
我仍然觉得使用Oracle(例如)PostgreSQL虽然很有趣...: - )