7

在 oracle 数据库中插入字符串时,一些国家字符被问号替换,即使它们被插入到 NCHAR 或 NVARCHAR 列中 - 这应该能够处理所有 Unicode 字符。

使用 Oracle 的 SQL Developer、sqlplus 或使用 JDBC 驱动程序会发生这种情况。

数据库 NLS_CHARACTERSET 设置为 WE8ISO8859P1(西欧 iso-8859-1) 用于 NCHAR 列的 NLS_NCHAR_CHARACTERSET 设置为 AL16UTF16。(UTF-16)

不在 NLS_CHARACTERSET 中的任何字符似乎都替换为倒置问号。

4

2 回答 2

26

编辑:请注意,在 Oracle 上处理 UTF 的最佳方法是使用数据库字符集 AL32UTF8 创建数据库,并使用普通的 varchar2 列。使用 nchar 列的问题之一是,默认情况下,当参数作为 nchar 发送时,oracle 不能为普通的 char/varchar2 列使用索引。

无论如何:如果您无法转换数据库:


首先,unicode 字面量需要以“n”为前缀,如下所示:

select n'Language - Språk - Język' from dual;

*) 8 位编码无法处理此文本

不幸的是,这还不够。

出于某种原因,数据库客户端的默认行为是将所有字符串文字转换为数据库字符集,这意味着即使在数据库看到字符串之前值也会被更改。

客户端需要一些配置才能将 unicode 字符插入 NCHAR 或 NVARCHAR 列:

Unix 上的 SQL Plus

这些 environemnet 变量设置 unix 环境和 sqlplus 以使用 UTF-8 文件,还配置 sqlplus 以发送 unicode 字符串文字。

NLS_LANG=AMERICAN_AMERICA.AL32UTF8
LC_CTYPE="en_US.UTF-8"
ORA_NCHAR_LITERAL_REPLACE=true

(en_US.UTF-8 用于 Solaris - Linux 或其他系统可能需要不同的字符串,用于locale -a列出支持的语言环境。)

JDBC 驱动程序

使用 Oracle JDBC 驱动程序的应用程序需要定义以下系统属性才能以 unicode 发送字符串文字。

-Doracle.jdbc.defaultNChar=true 
-Doracle.jdbc.convertNcharLiterals=true

SQL 开发人员

找到 sqldeveloper.conf,并添加以下行:

AddVMOption -Doracle.jdbc.defaultNChar=true 
AddVMOption -Doracle.jdbc.convertNcharLiterals=true

Microsoft Windows 上的 SQL Plus

如果 Microsoft Windows 或 Toad 上的 SQLplus 完全处理 utf-8,我还没有尝试过。Sqlplusw.exe 可以做到这一点,下面的注册表设置可以做到这一点。

NLS_LANG=AMERICAN_AMERICA.AL32UTF8
ORA_NCHAR_LITERAL_REPLACE=true
于 2011-06-28T16:26:56.530 回答
1

谢谢 KarlP - 这让我走了。回顾对我有用的东西。

在 linux 上使用 sqlplus 将中文(任何 utf8)文本插入非 unicode 数据库(例如:ISO8859 等)的 nvarchar 列。

我系统上的这些 db 参数,注意 char 的单字节编码,但 nchare 的多字节编码。NLS_CHARACTERSET WE8ISO8859P1
NLS_NCHAR_CHARACTERSET AL16UTF16

例如:

INSERT INTO tt values ( N'气前照灯' );

字符串前面的“N”很重要。另外,必须在启动 sqlplus 之前设置环境,

# Important to tell sqldeveloper what encoding is needed.
export NLS_LANG=AMERICAN_AMERICA.UTF8
# Others might find AMERICAN_AMERICA.AL32UTF8 or whatever better suits.

# ** THIS MATTERS - DOES NOT WORK WITHOUT !! 
export ORA_NCHAR_LITERAL_REPLACE=true
于 2017-11-28T18:39:25.063 回答