Oracle PL/SQL 中的字符编码问题

Posted

技术标签:

【中文标题】Oracle PL/SQL 中的字符编码问题【英文标题】:Character encoding issue in Oracle PL/SQL 【发布时间】:2012-09-15 18:43:21 【问题描述】:

我在从 db 表中提取数据时遇到字符差异问题。

我已经编写了一个 PL/SQL 代码来从我的 db 表中将一些数据假脱机到 .txt 文件,并使用 unix shell 运行这个 sql,但是当我获取假脱机文件时,结果集是从一个在后端。

例如:

At back end: SADETTÝN

In Spooled txt file :  SADETTŸN 

如果您查看Y 字符,它是一个改变的字符。我想以后端的方式保留所有字符。

我的数据库的字符集:

SELECT * FROM v$nls_parameters WHERE parameter LIKE 'NLS%CHARACTERSET'
PARAMETER              VALUE 
NLS_CHARACTERSET       WE8ISO8859P1 
NLS_NCHAR_CHARACTERSET WE8ISO8859P1 

和 Unix NLS_LANG 参数:

$ echo $NLS_LANG
AMERICAN_AMERICA.WE8ISO8859P1

我尝试将 NLS_LANG 参数更改为 WE8ISO8859P9(土耳其字符集),但没有帮助!

谁能告诉我这个问题的解决方案?

【问题讨论】:

您的数据库的字符集可能是这样,但不能保证您用于假脱机的终端可以支持Ý,或者您的操作系统可以。 你是如何生成文本文件的?你在用UTL_FILE吗?还是你在做别的事情?您是否在十六进制编辑器中打开了文件,以查看在文本编辑器中被解释为 Ÿ 的文件中的实际十六进制值? @JustinCave 我在 SQL*PLUS 中使用简单的假脱机概念。我会尝试使用十六进制编辑器打开我的文件并让你知道。谢谢。 要查看 SQL 中的字符代码,您可以“从表中选择转储(column_name)”。 @Justin Cave 用简短的解释编辑了我的问题。提前致谢。 【参考方案1】:

我假设您正在尝试使用“vi”或类似的东西来可视化您的文件。NLS_LANG 参数仅由您的数据库用于导出到您的文件。对于您的编辑器(vi),您需要将 LANG 参数设置为NLS_LANG 的对应值。 示例:对于 ISO8859P1 美式英语,您必须这样做 导出 LANG=en_US.ISO8859-1 换句话说,您的文件很好,只是您的编辑不知道如何处理您的土耳其语字符。

【讨论】:

感谢您的建议。由于我的文件是 txt 文件,我只是使用 pcput 将文件保存到我的磁盘,然后使用简单的记事本打开它。结果是“更改的字符” 不过我尝试按照您的建议更改 LANG 参数: $ echo $export LANG=en_US.ISO8859-1 LANG=en_US.ISO8859-1 结果在记事本和 vi 编辑器中是相同的。 fyi..VI EDITOR中的结果是:SADETT\335N(和以前一样)请指教。 就像我说的那样,您的文件很好。您看到的“/335”是 HEX DD 的八进制代码,在 ISO8859-1 中是“Ý”。(请参阅link)。有时vi 不显示 ascii 表的扩展字符(字符代码 128-255),但不是 unix 鉴赏家,我无法帮助您。要查看特殊字符,您需要使用具有正确编码的编辑器。例如,如果您使用 notepad++ 并在菜单 Encoding/Character Sets/Turkish 中选择 iso 8859 9,您甚至可以看到“İ”,它是您想要在“SAADETTİN”中看到的字符 :)。 而且我不会使用“pcput”来传输文件,因为正如您在上面所说的,pcput 似乎在传输过程中会更改文件。我会改用 ftp/sftp。【参考方案2】:

您应该使用 NCHAR 数据类型。如需更多信息,请访问 Oracle 文档 - SQL and PL/SQL Programming with Unicode

为了从 SQL*Plus 进行假脱机,您需要正确设置 NLS_LANG 环境变量。这是*** 中的一个类似问题。

【讨论】:

但是我的 char 和 nchar 字符集在 db 中是相同的,所以我认为没有必要使用 NCHAR 数据类型。 SELECT * FROM v$nls_parameters WHERE parameter LIKE 'NLS%CHARACTERSET'PARAMETER VALUE NLS_CHARACTERSET WE8ISO8859P1 NLS_NCHAR_CHARACTERSET WE8ISO8859P1如果我错了请纠正我。 更多信息。甚至我在 Unix 客户端操作系统上的 nls_lang 参数也与 DB 上的相同: $ echo $NLS_LANG AMERICAN_AMERICA.WE8ISO8859P1

以上是关于Oracle PL/SQL 中的字符编码问题的主要内容,如果未能解决你的问题,请参考以下文章

来自 Oracle pl/sql 的电子邮件中的特殊字符

Oracle PL/SQL 参数值来自字符串中的参数名称

pl/sql developer中文乱码,为啥呢?怎么解决?Oracle问题

Oracle PL/SQL 中的存储过程

pl/sql developer中文乱码,为啥呢?怎么解决?Oracle问题

带输入参数的 Oracle PL/SQL 函数