1

我使用以下在 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
4

2 回答 2

0

如果 Oracle 数据库字符集是 AL32UTF8,为什么列定义为 NVARCHAR2?这意味着您希望这些列使用国家字符集(通常为 AL16UTF16,但在您的数据库中可能不同)进行编码。除非您主要存储亚洲语言数据(或其他需要在 AL32UTF8 中存储 3 个字节的数据),否则当数据库字符集支持 Unicode 时,在 Oracle 数据库中创建 NVARCHAR2 列相对不常见。

一般来说,坚持使用数据库字符集(CHAR 和 VARCHAR2 列)比尝试使用国家字符集(NCHAR 和 NVARCHAR2 列)要好得多,因为在开发/配置方面。由于您不会通过选择 NVARCHAR2 数据类型来增加可以编码的字符集,因此我敢打赌,您会更喜欢 VARCHAR2 数据类型。

于 2008-12-03T16:37:41.177 回答
0

谢谢贾斯汀。

我不能说我仍然完全了解如何在 VARCHAR2 和 NVARCHAR2 之间进行选择。我曾尝试在我的约会中使用 VARCHAR2(其中确实包括许多不同的语言,包括欧洲和亚洲),但当时并没有奏效。

不过,我又玩了一点,我发现使用贾斯汀的建议在这种组合中有效:

  • AL32UTF8 数据库字符集
  • VARCHAR2 列类型
  • 在启动 sqlplus.exe 之前设置 NLS_LANG=.UTF8
  • 使用 UTF-8 的数据文件(即包含所有 INSERT 语句的文件)
  • 使用 SQL_C_WCHAR 从数据库中插入和提取字符串

我仍然觉得 Oracle 不像(例如)PostgreSQL 那样有趣...... :-)

于 2008-12-03T20:33:14.853 回答