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

发布于 2024-11-17 19:33:01 字数 324 浏览 3 评论 0原文

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

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

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

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

When inserting strings in an oracle database, some national characters are replaced with question marks, even though they are
inserted in an NCHAR or NVARCHAR column - that should be able to handle all Unicode characters.

This happens using either Oracle's SQL Developer, sqlplus or using the JDBC driver.

The database NLS_CHARACTERSET is set to WE8ISO8859P1 (western european iso-8859-1)
The NLS_NCHAR_CHARACTERSET used for NCHAR columns is set to AL16UTF16. (UTF-16)

Any character not in the NLS_CHARACTERSET seems to be replaced with a inverted question mark.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦境 2024-11-24 19:33:01

编辑:请注意,在 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 Developer

找到 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

Edit: Note that the best way to handle UTF on Oracle is to create the database using the database character set AL32UTF8, and use ordinary varchar2 columns. One of the problems with using nchar columns is that oracle can't use indexes for ordinary char/varchar2 columns when arguments are sent as nchar by default.

Anyway: If you can't convert the database:


First, unicode literals needs to be prefixed with an 'n', like this:

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

*) 8-bit encodings can't handle this text

Unfortunately, that is not enough.

For some reason, the default behaviour for database clients is to translate all string literals to the database character set,
meaning that values will be changed even before the database gets to see the string.

The clients need some configuration in order to be able to insert a unicode character into an NCHAR or NVARCHAR column:

SQL Plus on Unix

These environemnet variables sets up the unix environment and sqlplus to use UTF-8 files,
and also configure sqlplus to send string literals in unicode.

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

(en_US.UTF-8 is for Solaris - Linux or other systems may need different strings, use locale -a to list supported locales.)

JDBC Driver

Applications using Oracles JDBC driver needs to have the following system property defined to send strings literals in unicode.

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

SQL Developer

Locate sqldeveloper.conf, and add the following lines:

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

SQL Plus on Microsoft Windows

I haven't tried if SQLplus on Microsoft Windows or Toad handles utf-8 at all.
Sqlplusw.exe may do that, and the following registry settings may do the trick.

NLS_LANG=AMERICAN_AMERICA.AL32UTF8
ORA_NCHAR_LITERAL_REPLACE=true
画离情绘悲伤 2024-11-24 19:33:01

谢谢 KarlP - 这让我继续前进。回顾一下对我有用的事情。

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

我的系统上的这些数据库参数,请注意 char 的单字节编码,但 ncare 的多字节编码。
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

Thanks KarlP - that got me going. Recapping what worked for me.

Inserting chinese ( any utf8 ) text into an nvarchar column of a non-unicode database ( eg: ISO8859 etc ), using sqlplus on linux.

These db params on my system, note a single byte encoding for char, but multibyte for nchare.
NLS_CHARACTERSET WE8ISO8859P1
NLS_NCHAR_CHARACTERSET AL16UTF16

eg:

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

The 'N' prepending the string is important.
Also, must set the env before starting 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文