要查看当前设置,请使用 “locale” 命令,如下所示: $ locale 输出示例: LANG=fr_FR LC_CTYPE="fr_FR.iso885915@euro" LC_COLLATE="fr_FR.iso885915@euro" LC_MONETARY="fr_FR.iso885915@euro" LC_NUMERIC="fr_FR.iso885915@euro" LC_TIME="fr_FR.iso885915@euro" LC_MESSAGES="fr_FR.iso885915@euro" LC_ALL=fr_FR.iso885915@euro 大多数 Unix 版本默认设置为: $ locale LANG= LC_CTYPE="C" LC_COLLATE="C" LC_MONETARY="C" LC_NUMERIC="C" LC_TIME="C" LC_MESSAGES="C" LC_ALL= “C”是指 US7ASCII,这意味着仅可显示 a-z、A-Z 和 0-9。 我们建议尽可能使用 UTF-8,如下所示: $ locale LANG=en_US LC_CTYPE="en_US.UTF-8" LC_COLLATE="en_US.UTF-8" LC_MONETARY="en_US.UTF-8" LC_NUMERIC="en_US.UTF-8" LC_TIME="en_US.UTF-8" LC_MESSAGES="en_US.UTF-8" LC_ALL=en_US.UTF-8 如果您已经选择了一个值,例如在 Linux 上使用 “en_US.UTF-8”,可进行如下设置: $ export LC_ALL=en_US.UTF-8 或 % setenv LC_ALL en_US.UTF-8 请注意,此命令的输出/语法在不同 Unix 环境中并不完全相同。如果您对如何在特定 Unix/Linux 版本中配置用户环境有任何问题,请咨询您的 OS 供应商。
要查看所有安装的 locale,请执行以下语句: $ locale -a 示例输出: $ locale -a POSIX common en_US.UTF-8 C iso_8859_1 iso_8859_15 en_CA en_CA.ISO8859-1 en_US en_US.ISO8859-1 en_US.ISO8859-15 en_US.ISO8859-15@euro fr_CA fr_CA.ISO8859-1 th th_TH th_TH.TIS620 ja ...
这将列出 Unix 计算机上所有已安装的 locale。
例如,如果您想要使用 “fr_FR.iso885915@euro”,但它不在列表中,则您需要先安装它。
如果您将用户环境设置为未安装的 locale,您不会收到错误消息,但该设置可能不起作用。
请注意,您需要安装完全匹配的 locale,如果您安装了 “fr_FR.UTF-8”或“UTF-8”,但想要使用 “en_US.UTF-8”,则需要安装 “en_US.UTF-8”。
在上边的示例中,“en_US.UTF-8” 存在于列表中,因此我们可以在此服务器上使用该设置。
需要检查 telnet/ssh 软件是否已正确配置。telnet/ssh 软件负责将 Unix locale 转换给客户端环境(多半为 Windows 系统)。
建议首先使用免费的 PUTTY 客户端进行尝试,据所知,它是与 Unicode 最佳兼容的一款客户端工具。可从此站点下载 Putty:http://www.chiark.greenend.org.uk/~sgtatham/putty/
如示例中一样,在 Unix 端使用 “en_US.UTF-8”,则在 Putty 中更改如下设置:
打开配置窗口,导航到“Window(窗口)”、“Translation(转换)”,并将“Received data assumed to be in which character set(假定接收到的数据使用此字符集)”设置为“UTF-8”
。这需要与 Unix shell 端的编码匹配。如果locale不是UTF-8, 但是比如是en_US.ISO8859-1那么选择”ISO-8859-1:1998 (Latin-1, West Europe)”
导航到“Window(窗口)”、“Appearance(外观)”,然后在“Font used in the terminal window(终端窗口中使用的字体)”中选择一种字体,以便支持您想要使用/查看的语言。
在 Windows 客户端,大多数非亚洲语言可以使用默认的“Courier New” Windows 字体,“Arial Unicode MS”为更加完整的字体。“Arial Unicode MS”通常在所有安装了 Office 2002 或更高版本的 Windows 客户端均可用,可支持各式各样的字符。要了解此字体支持哪些语言,请参阅 http://support.microsoft.com/kb/q287247/ 。如果未安装 office 2002,则可以尝试 GNU FreeFont http://www.gnu.org/software/freefont/index.html 集合。另一个关于 Unicode 字体的非常优秀的资源是 Alan Wood’s website。例如,Shareware“Code2000”字体是最完整的“通用”字体之一。
在 Windows 上,Windows 工具“字符映射表”可用于查看字体中包含哪些字符,或者您可以在编辑器中(如 Wordpad)输入字符并选择字体,然后看这些字符是否正确显示。
如果使用 Putty 可以正确显示,但使用您的 telnet/ssh 软件包却不可正确显示,请咨询您的 telnet/ssh 软件供应商。
如果您不使用 telnet/ssh 客户端而使用“真正的”Unix 显示器,请参阅 Note 265090.1 How to check Unix terminal Environments for the capability to display extended characters.
当执行完下列操作后:
1) 正确配置 LC_ALL
2) 确认所使用的 locale 已安装
3) 配置好 telnet/ssh 客户端
然后您就可以使用 NLS_LANG 匹配 locale。
NLS_LANG 的构成为:NLS_LANG=<NLS_LANGUAGE>_<NLS_TERRITORY>.<clients characterset>
以 locale “en_US.UTF-8”为例,这意味着应该将 NLS_LANG 设置为 =AMERICAN_AMERICA.AL32UTF8;如果 locale 设置为“en_US.UTF-8”,则相应的 NLS_LANG 设置将为 AMERICAN_AMERICA.AL32UTF8。
请注意: * UTF-8 (Unix) 和 UTF8/AL32UTF8 (Oracle) 的表示法之间的区别 * NLS_LANG 的 NLS_LANGUAGE 和 NLS_TERRITORY 设置 与在客户端上“查看”字符/在数据库中存储字符的能力无关。 NLS_LANG 设置为 JAPANESE_JAPAN.WE8ISO8859P15 将不允许存储日文,因为 WE8ISO8859P15 不识别日文字符。但 NLS_LANG 设置为 AMERICAN_AMERICA.UTF8 将允许使用/存储日文(假定您的 telnet/ssh 客户端和 Locale 设置正确,且您的数据库可以存储日文 - 例如使用 UTF8 或 AL32UTF8 NLS_CHARACTERSET 的数据库) * 要使 NLS_LANGUAGE 和 NLS_TERRITORY 匹配 LC_ALL 中的 language(_territory) 值,请在 database globalizaton support guide appendix A. 中查看相应的 Oracle 语言和地区值。 因此,以 Unix 用户身份登录并执行以下操作: a) 对照 locale 检查 LC_ALL 是否设置正确(假定此处为 en_US.UTF-8) b) 仔细检查 Telnet/ssh 客户端配置(假定此处 Putty 按第 3 点所述进行配置) c) 设置 NLS_LANG 以匹配 locale 设置$ export NLS_LANG=AMERICAN_AMERICA.AL32UTF8 或 % setenv NLS_LANG AMERICAN_AMERICA.AL32UTF8 之后通过下边的小窍门检查 sqlplus 侦测到的 NLS_LANG 设置: $ sqlplus /nolog SQL>@.[$NLS_LANG]. 如果得到下边的结果: SQL>@.[$NLS_LANG]. SP2-0310: unable to open file ".[AMERICAN_AMERICA.AL32UTF8]..sql" '[]'中包含的"文件名"就是 sqlplus 将会使用的 NLS_LANG 设置。 如果得到下边的结果: SQL>@.[$NLS_LANG]. SP2-0310: unable to open file ".[$NLS_LANG]..sql" 那么表示 NLS_LANG 没有设或者 sqlplus 没有侦测到。 如果得到" SP2-0310: unable to open file ".[$NLS_LANG]..sql" " 但是下边的命令能返回 AMERICAN_AMERICA.AL32UTF8: SQL>HOST ECHO $NLS_LANG 那么表明 NLS_LANG 设置了但是没有在环境中 *export* d) 使用 sqlplus 连接到数据库并查询一些数据。 一个很好的检查方法是执行以下语句“select UNISTR('\20AC') from dual;”。如果选择使用9i 或更高版本数据库,和一个正确的 UTF-8 或 ISO8859-15 Unix 环境,则一个欧元符号会被正确的显示出来,因为这样的环境可以正确处理欧洲语言(AL32UTF8、WE8MSWIN1252、...)。如果可以显示欧元符号但数据库中存储的数据未正确显示,则表明客户端已正确配置,但数据库中的现有数据现在/过去未正确存储。将需要更正数据库中的现有数据,直至其可在正确配置的客户端显示 Note:225938.1 Database Character Set Healthcheck. 如果此方法有效,则将用户配置文件中的 NLS_LANG 也设置为这个值以用于 sqlplus。 如果已完成,则针对在 sqlplus 中交互式插入和查询数据进行了正确配置。 但是,这并不意味着此设置可用于所有应用程序。 NLS_LANG 用于让 Oracle 客户端知道哪些编码/字符集数据将传输到客户端库。如果在此 Unix 计算机上运行 Web 应用程序且输出 iso-8859-1 数据,则对于该应用程序,正确的 NLS_LANG 为 WE8ISO8859P1(即使 Unix locale 为 UTF-8)
如果未看见预期的字符,则请再次检查您的设置。剩余的最常见问题是您的 Telnet/ssh 仿真程序未正确配置。 然而,也可能是您的数据库中数据不正确。 一个简单的检查方法是: 使用 Windows 客户端,从以下地址下载并安装 SqlDeveloper http://www.oracle.com/technology/products/database/sql_developer/index.html ,连接到您的数据库并查看数据在该工具中是否正确显示。 如果数据可以在 SqlDeveloper 中显示,则数据库中的数据是正确的,问题在于客户端。 如果数据未在 SqlDeveloper 中显示,则表明数据库中的数据不正确,这意味着即使您的客户端已正确配置,数据也无法正确显示。 较难的检查方法是: 如果使用 select 语句,例如“select ename from scott.emp where empno='7369';”来返回一行数据,则执行以下语句“select dump(ename,1016),ename from scott.emp where empno='7369';”。 可以在以下文档中查看代码是否匹配您期望数据库字符集中的字符 ( select value from NLS_DATABASE_PARAMETERS where parameter='NLS_CHARACTERSET'; ) 或者如果使用的是 (AL32)UTF8 数据库,请使用 Note 69518.1 Storing and Checking Character Codepoints in a UTF8/AL32UTF8 (Unicode) database 如果不知道问题是什么原因造成的,请新开一个服务请求,参阅以下文档并提供所需信息: * Note 226692.1 Finding out your NLS Setup 文档中要求的信息。 * 在的环境中执行这个select语句“select dump(ename,1016),ename from scott.emp where empno='7369';”并用 spool 保存结果到文件。(!请勿直接复制粘贴!)
第 1-4 步应足以解决 99% 的问题,本文档的剩余部分将讨论深入调试 在某些平台上,使用下列语法可以有效地获取关于 实际使用的代码页的更多详细信息: $ locale LC_CTYPE | head HP-UX 环境中的输出示例: "" "" "iso885915" "" Linux 环境中的输出示例: upper;lower;alpha;digit;xdigit;space;print;graph;blank;cntrl;punct;alnum;combining;combining_level3 toupper;tolower;totitle 16 1 ISO-8859-15 70 84 1 0 1 $ locale LC_CTYPE | head upper;lower;alpha;digit;xdigit;space;print;graph;blank;cntrl;punct;alnum;combining;combining_level3 toupper;tolower;totitle 16 6 UTF-8 70 84 1 0 1 在 Solaris、AIX、TRU64 上,此语法不能提供相关的补充信息。 要查找关于这些设置的更多详细信息: 在 Solaris 上,请查看 /usr/lib/locale。 在 AIX 上,请查看 /usr/lib/nls/README 在 TRU64 上,请查看 /usr/lib/nls 在 HP-UX 上,请查看 /usr/lib/nls/config 在 Linux 上,请查看 /usr/share/locale/locale.alias 如何检查操作系统管理的字符编码: 要了解 Unix 环境中针对字符所生成的字符编码, 可以按如下所示使用“od”命令(使用 iso-8859-1 locale 的示例): $ od -xc é 0000000 00e9 351 \0 0000001 正如您所见,hexa-decimal 编码 e9 对应于“é”(小写 e 重读音节) 351 是对应的八进制值(八进制为 od 命令的固有状态)。 您还可以使用“echo”命令检查对应于字符编码的字符,如下所示: 对于 Solaris、AIX、HP-UX、TRU64: $echo '\0351' é 对于 Linux: $echo -e '\0351' é 正如所见,echo 使用八进制值,因此需要将要检查的值转换为八进制。
不需要,Locale 和 NLS_LANG 设置(如果适用,还包括 telnet/ssh config)需要互相匹配,但从技术角度看它们均与数据库字符集无关,并且它们仅针对该客户端环境相关。
假定您使用 AL32UTF8 NLS_CHARACTERSET 数据库。如果将 Unix 环境配置为(例如)fr_FR.iso885915@euro(相匹配的 NLS_LANG 为 FRENCH_FRANCE.WE8ISO8859P15),则您可以在 Unix shell 中查看/插入欧元字符和法文或西班牙文,但无法查看/插入俄文或中文(也就是 iso885915 中未定义的任何语言)。
然而,如果您使用可以存储/处理这些语言的远程客户端(例如使用 Sqldeveloper 的 Windows 客户端),则可以向 AL32UTF8 数据库插入这些语言或从该数据库选择这些语言。原因很简单,因为服务器 NLS_LANG/Locale 设置仅在服务器本身作为客户端的情况下有关。
许多客户都遇到过这样的麻烦,由于将数据库 NLS_CHARACTERSET 更改为 (AL32)UTF8 从而需要“更正”Unix shell,其实只要不将 Unix 服务器本身作为客户端用于数据输入,则可以免去这些麻烦。您其实更应该担心的是最终用户实际插入数据的客户端。能够在服务器上使用 sqlplus 查看/插入中文可能是不错的体验,但即使奏效,这也与您的 Windows 客户端(例如)无关,因为 Windows 客户端设置与 Unix 端完全无关。
对于 Windows 客户端,请参阅 Note 179133.1 The correct NLS_LANG in a Windows Environment
请注意,在服务器上加载普通文本文件时,sqlldr 的字符集取决于该文本/普通文件的字符集,而不是数据库字符集或所使用的 Unix locale,
请参阅 Note 227330.1 Character Sets & Conversion – Frequently Asked Questions / point 18. What is the best way to load non-US7ASCII characters using SQL*Loader or External Tables?
一个最常被问到的问题是:对于一个NLS_CHARACTERSET是”xx8MSWIN12xx”(如WE8MSWIN1252等等)的数据库,在Unix client上正确的LANG和NLS_LANG设置是什么?
Server上使用的LANG 和 NLS_LANG并不会影响通过Listener连接进来的客户端。.
很可能你是通过telnet/ssh连接上来做一些管理的工作,而不是真正的输入应用程序数据。.
在这种情况下,可以在Unix profile中把LANG设置为iso-8859-1,把NLS_LANG设置为AMERICAN_AMERICA.WE8MSWIN1252.
从技术上讲这并不是100%正确,但却是个好方案,可以在sqlplus里很简单的运行”xx8MSWIN12xx”编码的脚本(比如在windows操作系统中创建的脚本),并且对于传统的exp/imp你不需要担心NLS_LANG的设置。.
注意:很可能不能够在telnet环境里看到特殊字符,如欧元符号或者阿拉伯文。.
但是在telnet环境中看不到特殊字符,并不影响通过listener连接进来的(Windows)客户端.
如果想仔细检查数据,那么我们建议你使用SqlDevelper来检查;这个工具是一个非常好的客户端,它不需要任何NLS的设置。