将国家字符插入oracle NCHAR或NVARCHAR列不起作用

时间:2011-06-28 16:22:36

标签: java oracle unicode sqlplus nvarchar

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

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

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

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

2 个答案:

答案 0 :(得分:20)

编辑:请注意,在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驱动程序

使用Oracles JDBC驱动程序的应用程序需要定义以下系统属性,以便在unicode中发送字符串文字。

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

SQL Developer

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

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

Microsoft Windows上的SQL Plus

如果Microsoft Windows上的SQLplus或Toad完全处理utf-8,我还没有尝试过。 Sqlplusw.exe可能会这样做,并且以下注册表设置可以解决问题。

NLS_LANG=AMERICAN_AMERICA.AL32UTF8
ORA_NCHAR_LITERAL_REPLACE=true

答案 1 :(得分:0)

谢谢KarlP - 让我走了。重新利用对我有用的东西。

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

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

例如:

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

字符串前面的'N'很重要。 另外,必须在启动sqlplus之前设置env,

# 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