语言环境 (locale) 是解决特定语言和国家/地区的语言和文化要求的信息集合。通常,语言环境相关数据用于为日期、时间、数字和货币的格式化和解析提供支持。过去,提供正确的当前语言环境数据一直由各平台所有者或供应商来负责,而这可能导致语言环境数据不一致或出错。
设置 NLS_LANG 环境参数是为 Oracle 软件指定语言环境行为的一种简便的方法。利用此方法可以设置客户端应用和数据库服务器使用的语言和区域。还可以指示客户端的字符集,该字符集与客户端程序输入或显示的数据的字符集相对应。
UNIX 平台以本地环境变量的形式设置 NLS_LANG。Windows 平台则在注册表中设置 NLS_LANG。
NLS_LANG 参数包含三个组成要素:语言、区域和字符集。该参数使用以下格式(带标点)来指定:
NLS_LANG = language_territory.charset
NLS_LANG 参数的每个组成要素各控制一部分全球化支持特性的操作:
语言
指定语言约定,例如 Oracle 消息、排序、日期名称和月份名称所使用的语言。每种受支持的语言均有一个唯一的名称,例如 AMERICAN、FRENCH 或 GERMAN。语言参数指定区域和字符集参数的默认值。如果未指定语言,则该值默认为 AMERICAN
区域
指定区域约定,例如默认日期、货币和数字格式。每个受支持的区域均有一个唯一的名称,例如,AMERICA、FRANCE 或 CANADA。如果未指定区域,则将从语言值中得出该值。
字符集
指定客户端应用使用的字符集(通常是与用户终端字符集或 OS 字符集相对应的 Oracle 字符集)。每个受支持的字符集均有一个唯一的缩写词,例如 US7ASCII, WE8ISO8859P1, WE8DEC, WE8MSWIN1252 或 JA16EUC。每种语言都有与之关联的默认字符集。
注意:
NLS_LANG
定义的所有组成要素都是可选的,未指定的任何项目均使用其默认值。在指定区域或字符集时,必须包括前面的分隔符[区域之前的下划线 (_) 和字符集之前的句点 (.)]。否则,该值将被解析为语言名称。
例如,如果只设置 NLS_LANG
的区域部分,请使用以下格式: NLS_LANG=_JAPAN
本文其余内容将重点介绍 NLS_LANG 设置中的字符集,字符集最难理解但又必须正确设置。
在许多情况下,用户已经在 Oracle 安装过程中或在安装后手动设置了 NLS_LANG。为了确认,您可以使用以下方法对 SQL*Plus 获取 NLS_LANG 值:
UNIX 平台:
SQL> HOST ECHO $NLS_LANG
这将返回该参数的值。
Windows 平台:
在 Windows 上,NLS_LANG 通常会在注册表中设置,但也可能在环境中设置,不过后者不太常见。环境中的值优先于注册表中的值,并且将应用于服务器上的所有 Oracle_Home。另外请注意,如果设置了任意 USER 环境变量,则该变量优先于所有 SYSTEM 环境变量(这是 Windows 的行为,与 Oracle 无关)。
检查是否在环境中设置了该变量:
SQL> HOST ECHO %NLS_LANG%
如果仅返回 %NLS_LANG%,则表示未在环境中设置该变量。
如果设置了该变量,则会返回下面这样的结果
ENGLISH_UNITED KINGDOM.WE8ISO8859P1
如果环境中未设置 NLS_LANG,请检查注册表中的值:
SQL>@.[%NLS_LANG%].
如果返回如下消息:
Unable to open file.[ENGLISH_UNITED KINGDOM.WE8ISO8859P1].
那么,括号之间的“文件名”是注册表参数的值。
如果返回如下结果:
Unable to open file ".[%NLS_LANG%].",则表示注册表中也未设置 NLS_LANG 参数。
请注意 @.[%NLS_LANG%]. 方法返回的是 SQL*Plus 可执行程序已知的 NLS_LANG,而不会读取注册表本身。但是,如果先运行 HOST 命令,环境中未设置 NLS_LANG,那么只要 @.[%NLS_LANG%]. 返回了有效值,就可以确认注册表中设置了该变量。
所有其他 NLS 参数可通过以下方式获得:
SELECT * FROM NLS_SESSION_PARAMETERS;
注意:
SELECT USERENV ('language') FROM DUAL; 将提供会话的语言>_区域>,但 DATABASE 字符集并不是客户端的,因此所返回的值并不是客户端的完整 NLS_LANG 设置!
本部分描述在数据库客户端/服务器模型中采纳 NLS 参数的优先顺序。(这不包括瘦 JDBC 连接)
您可以在 3 个级别上设置 NLS 参数:数据库、实例和会话。如果在多个级别上定义了一个参数,则其优先级规则非常简单:
SELECT * from NLS_SESSION_PARAMETERS;
这些是当前 SQL 会话使用的设置。
它们反映了(按以下顺序):
因此,如果设置了 NLS_LANG=_BELGIUM.WE8MSWIN1252,则会返回:
PARAMETER VALUE
NLS_LANGUAGE AMERICAN
NLS_TERRITORY BELGIUM
NLS_CURRENCY <此处为欧元符号>
NLS_ISO_CURRENCY BELGIUM
注意:
NLS_LANG=_BELGIUM.WE8MSWIN1252(正确)与
NLS_LANG=BELGIUM.WE8MSWIN1252(错误)之间的区别,您需要将 "_" 设置为分隔符。
因此,如果您设置了 NLS_LANG=ITALIAN_.WE8MSWIN1252,则会返回:
PARAMETER VALUE
NLS_LANGUAGE ITALIAN
NLS_TERRITORY ITALY
NLS_CURRENCY <此处为欧元符号>
NLS_ISO_CURRENCY ITALY
注意:
请注意 NLS_LANG=ITALIAN_.WE8MSWIN1252(正确)与
NLS_LANG=ITALIAN.WE8MSWIN1252(错误)之间的区别,您需要将 "_" 设置为分隔符。
因此,如果您设置了 NLS_LANG=.WE8MSWIN1252,则会返回:
PARAMETER VALUENLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY AMERICA
Note:
The difference between NLS_LANG=.WE8MSWIN1252 (correct) and
NLS_LANG=WE8MSWIN1252 (incorrect), you need to set the "." as separator.
以"独立"设置的形式来设置 NLS_SORT、NLS_DATE_FORMAT 等参数,这些设置将取代由 NLS_LANG 的 _ 部分得到的默认值。
因此,如果您设置了 NLS_LANG=AMERICAN_AMERICA.WE8MSWIN1252 和 NLS_ISO_CURRENCY=FRANCE,则会返回:
PARAMETER VALUE
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY FRANCE
默认值:
* 如果未设置 NLS_DATE_LANGUAGE 或 NLS_SORT,则使用由
NLS_LANGUAGE
得到的设置。* 如果未设置 NLS_CURRENCY、NLS_DUAL_CURRENCY、NLS_ISO_CURRENCY、NLS_DATE_FORMAT、NLS_TIMESTAMP_FORMAT、NLS_TIMESTAMP_TZ_FORMAT 和 NLS_NUMERIC_CHARACTERS,则使用由 NLS_TERRITORY 得到的设置
<Language>_<Territory>.US7ASCII 和
<Language>_<Territory> 部分的值将使用
NLS_INSTANCE_PARAMETERS 中的值。NLS_SORT 等在客户端上以“独立”方式定义的参数则会被忽略。
Note:
* If set, client parameters (NLS_SESSION_PARAMETERS) always take precedence over NLS_INSTANCE_PARAMETERS and NLS_DATABASE_PARAMETERS.
* This behavior cannot be disabled on/from the server, so a parameter set on the client always has precedence above an instance or database parameter.
* NLS_LANG cannot be changed by ALTER SESSION, NLS_LANGUAGE and NLS_TERRITORY can. However NLS_LANGUAGE and /or NLS_TERRITORY cannot be set as "standalone" parameters in the environment or registry on the client.
* NLS_SESSION_PARAMETERS is NOT visible for other sessions. If you need to trace this then you have to use a logon trigger to create your own logging table (based on session parameters)
* The <clients characterset> part of NLS_LANG is NOT shown in any system table or view.
* On Windows you have two possible options, normally the NLS_LANG is set in the registry, but it can also be set in the environment, however this is not often done and generally not recommended to do so. The value in the environment takes precedence over the value in the registry and is used for ALL Oracle_Homes on the server if defined as a system environment variable.
* NLS_LANGUAGE in the session parameters also declares the language for the client error messages.
* You cannot "set" a NLS parameter in an SQL script; you need to use ALTER SESSION.
SELECT * from NLS_INSTANCE_PARAMETERS;
这些是在数据库启动时使用的数据库配置文件 init.ora 中的设置,或者是通过 ALTER SYSTEM 进行的设置。
如果参数未在 init.ora 中显式设置或通过 ALTER SYSTEM 进行定义,那么其值并不会由"高级"参数得出(NLS_SORT 等参数会从 NLS_SESSION_PARAMETERS 中的 NLS_LANGUAGE 得到默认值,但是对于 NLS_INSTANCE_PARAMETERS 来说并不是这样的)
Note:
* NLS_LANG is not an init.ora parameter; NLS_LANGUAGE and NLS_TERRITORY are so you need to set NLS_LANGUAGE and NLS_TERRITORY separately.
* You cannot define the or NLS_LANG in the init.ora
The client characterset is defined by the NLS_LANG on the client OS (see above).
* You cannot define the database characterset in the init.ora. The database characterset is defined by the "Create Database" command.
* These settings take precedence above the NLS_DATABASE_PARAMETERS.
* These values are used for the NLS_SESSION_PARAMETERS if the client the
NLS_LANG is NOT set.
* Oracle strongly recommends that you set the NLS_LANG on the client at least to
NLS_LANG=.<clients characterset>
* The NLS_LANGUAGE in the instance parameters also declares the language for the server error messages in alert.log and in trace files.
SELECT * from NLS_DATABASE_PARAMETERS;
如果数据库创建期间未在 init.ora 中显式设置任何相关参数,则默认值为 AMERICAN_AMERICA。如果数据库创建期间在 init.ora 中设置了这些参数,则可以在返回结果中看到这些设置。创建数据库后将无法更改这些设置。请勿尝试通过更新系统表来绕过这些设置!如果未设置 INSTANCE 和 SESSION 参数,则使用这些设置为数据库提供默认值。
注意:
* NLS_LANG 并非 init.ora 参数,但 NLS_LANGUAGE 和 NLS_TERRITORY 是 init.ora 参数。
因此,您需要单独设置 NLS_LANGUAGE 和 NLS_TERRITORY。
* 这些参数将被 NLS_INSTANCE_PARAMETERS 和 NLS_SESSION_PARAMETERS 覆盖。
* 您无法在 init.ora 中定义<客户端字符集>或 NLS_LANG。客户端字符集由客户端 OS 上的 NLS_LANG 定义。
* 您无法在 init.ora 中定义数据库字符集。
数据库(国家)字符集 NLS_(NCHAR)_CHARACTERSET) 由 "Create Database" 命令定义。
* 实例或会话参数无法覆盖 NLS_CHARACTERSET 和 NLS_NCHAR_CHARACTERSET 参数。
它们由 "CREATE DATABASE 命令中指定的值定义,并且不支持后续动态更改。请勿通过更新系统表来更改该字符集。这可能会损坏数据库,并且可能会导致无法再次打开数据库。
* 在数据库创建期间设置 NLS_LANG 不会影响 NLS_DATABASE_PARAMETERS。
* 数据库创建期间设置的 NLS_LANG 并不会对数据库国家字符集产生影响。
更多 SELECT 语句:
A) SELECT name,value$ from sys.props$ where name like '%NLS%';
这提供与 NLS_DATABASE_PARAMETERS 相同的信息。
您应当使用 NLS_DATABASE_PARAMETERS,而不是 props$。
请注意大写的 '%NLS%'
B) SELECT * from v$nls_parameters;
此视图显示当前会话参数以及 NLS_DATABASE_PARAMETERS 视图中所示的 * DATABASE* 字符集。
C) SELECT name,value from v$parameter where name like '%NLS%';
此视图提供与 NLS_INSTANCE_PARAMETERS 相同的信息。
请注意 '%NLS%' 的大小写
D) SELECT userenv ('language') from dual;
以及
SELECT sys_context('userenv','language') from dual;
这两个 SELECT 语句都将提供会话的 _ 和
DATABASE 字符集。数据库字符集与您启动此连接时使用的 NLS_LANG 字符集不同!因此请注意,尽管此查询的输出看起来类似于 NLS_LANG 变量的值,但实际上并不是。
E) SELECT userenv ('lang') from dual;
此 SELECT 语句提供 Oracle 为此会话的 NLS_LANGUAGE 设置定义的语言所使用的短代码。如果 NLS_LANGUAGE 设置为 French,则这将返回 "F",如果 NLS_LANGUAGE 设置为 English,则这将返回 "GB"
如果 NLS_LANGUAGE 设置为 American,则这将返回 "US",等等……
F) SHOW parameter NLS%
这将提供与 NLS_INSTANCE_PARAMETERS 相同的信息
在 UNIX 系统上以 US7ASCII 字符集创建一个数据库。连接至数据库的 Windows 客户端使用 WE8MSWIN1252 字符集(区域设置 -> 西欧/ACP 1252),DBA 则使用 UNIX shell (ROMAN8) 操作数据库。客户端和服务器上的 NLS_LANG 设置为 american_america.US7ASCII。
Note:
This is an INCORRECT setup to explain character set conversion, don't use it in your environment!
请重点注意以下要点(如前所述):
当客户端 NLS_LANG 字符集设置为与数据库字符集相同的值时,Oracle 会认为发送或接收的数据具有相同(正确)的编码,因此出于性能方面的考虑,可能不会进行任何转换或验证。客户端传递的数据将会逐比特地原样进行存储。
从 Windows 中将一个 ‘é’(带尖音符的小写拉丁字母)插入到包含一个 'char' 类型的 ‘TEST’ 列的 NLS_TEST 表中。
只要您是在使用 WE8MSWIN1252 字符集的 Windows 系统上对该列执行插入和选择操作,那么一切都会顺利运行。即便数据库的字符集定义为了 7 位,系统也不会进行任何转换,并且会插入 8 位并读回 8 位。这是因为一个字节是 8 位,而 Oracle 始终使用 8 位,即便在 7 位字符集的情况下也是如此。在正确的设置下,系统不会处理最高有效位,而只会处理 7 位。
出于某种原因,您需要从 UNIX 服务器进行插入。在对 Windows 客户端插入数据的表执行 SELECT 操作时,您会获得 ‘Ò’(带沉音符的大写拉丁字母 O),而不是 ‘é’。
如果在 UNIX 服务器上插入 ‘é’ 而在 Windows 客户端上对该行执行 SELECT 操作,则会获得 ‘Å’(顶部带圆圈的大写拉丁字母 A)。
根本原因在于,您数据库中的数据是不正确的。您要将 WE8MSWIN1252 字符集的 ‘é’ 的数值存储在数据库中,但您告诉 Oracle 这是 US7ASCII 数据,因此 Oracle 不会进行任何转换,而只是存储该数值(再次重申:由于 NLS_LANG 设置为 US7ASCII,因此 Oracle 认为客户端提供的是 US7ASCII 代码,并且由于数据库字符集也是 US7ASCII,因此,系统不会进行任何转换)。
当您在 UNIX 服务器上对同一列执行 SELECT 操作时,Oracle 同样认为该值是正确的,不对该值进行任何转换就将其传递给 UNIX 终端。
问题是,在 WE8MSWIN1252 字符集中,‘é’ 的十六进制值是 'E9’,而在 Roman8 字符集中,‘é’ 的十六进制值是 'C5'。Oracle 只是将数据库中存储的值 ('E9') 传递给 UNIX 终端,而 UNIX 终端认为这是字母 ‘?’,因为在其 (Roman8) 字符集中,十六进制值 'E9' 代表字母 ‘Ò’。因此,您将在 UNIX 终端屏幕上看到 ‘Ò’ 而不是 ‘é’ 。
反之,如果在 UNIX 上执行插入操作,然后在 Windows 客户端上执行 SELECT 操作,情况也是相同的,只是您会得到其他结果。
对此的解决办法是,在创建数据库时使用包含 ‘é’ 的字符集
(WE8MSWIN1252、WE8ISO89859P1、UTF-8 等),并将客户端和服务器上的 NLS_LANG 分别设置为 WE8MSWIN1252 和 WE8ROMAN8。此时如果您在客户端和服务器上插入 ‘é’,那么无论从哪个系统执行 SELECT 操作,您都将得到 ‘é’。Oracle 知道 UNIX 插入的十六进制值的 'C5’ 以及 WE8MSWIN1252 客户端插入的 'E9’ 均是 ‘é’,并且会在数据库中插入 ‘é’(数据库中的代码取决于您所选择的字符集)。
您不必在 UNIX、Windows 或其他 OS 客户端之间切换就能发现此类问题。如果您添加别的 Windows 客户端,让其使用另一种字符集并采用错误的 NLS_LANG 设置,则会出现相同的问题。
要指定客户端 Oracle 软件的语言环境行为,您需要设置 NLS_LANG 参数。这将设置客户端的语言、区域和字符集。您需要查看语言环境设置,并据此来设置 NLS_LANG 第三字段(字符集)。为此,请使用 "locale" 命令,如下所示:
$ locale
Example of output:
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 LC_CTYPE | head
Example of output
in a HP-UX environment
:
""
""
"iso885915"
""
Example of output in a Linux environment:
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
在这些情况下,请将 NLS_LANG 第三字段设置为 WE8ISO8859P15。在 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
要为这些"语言环境"设置设定选定值,您需要知道哪些值可用。要确定这些信息,请使用以下语法:
$ locale -a
随后,在选择某个值之后(例如 Linux 上的 UTF-8),您可以像下面这样进行设置:
$ export LC_ALL=UTF-8
或
% setenv LC_ALL UTF-8
Example of output after the setenv:
$ locale
LANG=fr_FR
LC_CTYPE="UTF-8"
LC_NUMERIC="UTF-8"
LC_TIME="UTF-8"
LC_COLLATE="UTF-8"
LC_MONETARY="UTF-8"
LC_MESSAGES="UTF-8"
LC_PAPER="UTF-8"
LC_NAME="UTF-8"
LC_ADDRESS="UTF-8"
LC_TELEPHONE="UTF-8"
LC_MEASUREMENT="UTF-8"
LC_IDENTIFICATION="UTF-8"
LC_ALL=UTF-8
$ 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
这种情况下,NLS_LANG 第三字段(字符集)应设置为 UTF8。
% setenv NLS_LANG American_America.UTF8
在 Windows 系统上,编码方案(字符集)由代码页指定。所定义的代码页用于支持共享通用书写系统的特定语言或语言组。从 Oracle 的角度来看,代码页和字符集这两个术语含义相同。请注意,在非中日韩环境中,Windows GUI 和 DOS 命令提示符并不使用相同的代码页。
因此,Windows 对 ANSI (sqlplusw.exe) 和 OEM (dos box - sqlplus.exe) 环境使用 2 个不同的字符集。
在注册表中:
在 Windows 系统上,应当确保已为每个 Oracle Home 设置 NLS_LANG 注册表子项:
您可以使用 Windows 注册表编辑器轻松修改此子项:
开始菜单 -> 运行...
输入 "regedit" 后单击 "ok"
,编辑以下注册表项:
对于 Oracle 第 7 版:
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE
对于 Oracle Database 第 8 版、第 8i 版和第 9i 版:
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOMEx\
其中,"x" 是标识 Oracle Home 的唯一编号。
HOME0 是首个安装
对于 Oracle Database 10g:
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_
其中有一个名为 NLS_LANG 的表项
启动 SQL*Plusw 之类的 Oracle 工具时,它会读取位于同一目录中的 oracle.key 文件的内容,以便确定将使用哪个注册表树,进而确定将使用哪个 NLS_LANG 子项。
注意:
未安装第 7 版时,HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE 中的 NLS_LANG 设置为 "NA",这会让一些人感到困惑。这用于保持后向兼容性,可以忽略之。
作为“系统”属性中的系统或用户环境变量:
注册表是 Windows 上的参数设置的主要存储库,但它并不是唯一可以设置参数的地方。NLS_LANG 可以作为“系统”属性中的系统或用户环境变量来进行设置 ,不过并不建议这样做。
此设置将应用于所有 Oracle Home。
要查看和修改它们:
右键单击 '我的电脑' -> '属性'
选择'高级'选项卡 -> 单击 '环境变量'
'用户变量'列表包含当前登录的特定 OS 用户的设置信息以及适用于所有用户的系统级变量。
由于这些环境变量优先于注册表中已设置的参数,因此除非有充分的理由,否则不应当在此位置设置 Oracle 参数。
作为命令提示符中定义的环境变量:
在使用 Oracle 命令行工具之前,您需要手动设置 NLS_LANG 参数。在 MS-DOS 命令提示符中,使用 set 命令,例如:
C:\> set NLS_LANG=american_america.WE8PC850
您已经知道了 NLS_LANG 的当前设置,接下来可以检查它是否与当前的 ANSI 代码页完全相符。ACP(ANSI 代码页)由 Windows 的"默认语言环境"设置来定义,因此如果您使用 UK Windows 2000 客户端并且希望输入西里尔文(俄语),则要通过更改"默认语言环境"来更改 ACP,以便能够输入俄语。
您可以在注册表中找到其值:
开始菜单 -> 运行...
输入 "regedit" 后单击 "是"
浏览以下注册表项:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\NLS\CodePage\
其中有一个名为 ACP 的表项(一路往下)。ACP 的值是您当前的 GUI 代码页,用于映射至 Oracle 名称。由于存在许多名称非常相似的注册表项,因此请确保查看注册表中的正确位置。
此外,以下 URL 提供了所有 Windows 版本的默认代码页列表:
http://www.microsoft.com/globaldev/reference/
(位于页面左侧的 REFERENCE 选项卡下)
OEM = 命令行代码页,ANSI = GUI 代码页
请注意,以下页面列出了香港 HKSCS: http://www.microsoft.com/hk/hkscs/
查找相应的 Oracle 客户端字符集:
根据上面找到的 ACP,在下表中查找 Oracle 客户端字符集。请注意,特定的 ACP 只有一个正确的值。
ANSI 代码页 (ACP) | Oracle 客户端字符集(NLS_LANG 的第三部分) |
---|---|
1250 |
EE8MSWIN1250 |
1251 |
CL8MSWIN1251 |
1252 |
WE8MSWIN1252 |
1253 |
EL8MSWIN1253 |
1254 |
TR8MSWIN1254 |
1255 |
IW8MSWIN1255 |
1256 |
AR8MSWIN1256 |
1257 |
BLT8MSWIN1257 |
1258 |
VN8MSWIN1258 |
874 |
TH8TISASCII |
932 |
JA16SJIS |
936 |
ZHS16GBK |
949 |
KO16MSWIN949 |
950 |
ZHT16MSWIN950 - 香港除外(见下文) |
这是 GUI SQL*Plus (sqlplusW.exe/ plus80W.exe / plus33W.exe) 所使用的字符集,该工具可通过 Windows 开始菜单启动。请注意 GUI SQL*Plus 与"DOS 模式" SQL*Plus 之间的差异。
在 Windows NT、2000 和 XP 上,您可以使用 UTF8 作为 Oracle 客户端字符集 (=NLS_LANG),不过这种情况下您只能使用显式支持此配置的客户端程序。这是因为 Win32 的用户界面并不是 UTF8,因此客户端程序需要在 UTF8(用于 Oracle 端)和 UTF16(用于 Win32 端)之间执行显式转换。
在注册表中进行设置:
使用 Windows 注册表编辑器将 Oracle Home 中的 NLS_LANG 设置为上面刚刚查找到的值。
除了 CJK(日语、韩语、简体中文和繁体中文)等个别例外情况之外,MS-DOS 模式使用的代码页(称为 OEM 代码页)不同于 Windows GUI(ANSI 代码页)。因此,在使用 Oracle 命令行工具之前(比如 SQL*Plus (sqlplus.exe / plus80.exe / plus33.exe ) 和命令行提示符下的 svrmgrl 等工具),您需要手动使用 “set” DOS 命令以环境变量的形式手动设置 NLS_LANG 参数。
对于日语、韩语、简体中文和繁体中文,MS-DOS OEM 代码页 (CJK) 与 ANSI 代码页相同,因此在此特殊情况下,无需在 MS-DOS 模式下设置 NLS_LANG 参数。
在所有其他情况下,您需要设置该参数以覆盖已与 ANSI 代码页匹配的 NLS_LANG 注册表项。新的 "MS-DOS 专用的" NLS_LANG 需要与 MS-DOS OEM 代码页相匹配,您可以在命令提示符下输入 chcp 来获得该代码页:
C:\> chcp
Active code page: 437
C:\> set NLS_LANG=american_america.US8PC437
如果未正确设置 MS-DOS 模式会话的 NLS_LANG 参数,则数据可能会因错误的字符集转换而受损。
使用以下列表查找与您的语言环境系统上使用的 MS-DOS 代码页相匹配的 Oracle 字符集:
MS-DOS 代码页 | Oracle 客户端字符集(NLS_LANG 的第三部分) |
---|---|
437 |
US8PC437 |
737 |
EL8PC737 |
850 |
WE8PC850 |
852 |
EE8PC852 |
857 |
TR8PC857 |
858 |
WE8PC858 |
861 |
IS8PC861 |
862 |
IW8PC1507 |
865 |
N8PC865 |
866 |
RU8PC866 |
注意:这是 GUI SQL*Plus 版本 (sqlplusW.exe / plus80W.exe / plus33W.exe) 的正确设置
如果您要测试"特殊"字符,那么务请使用此 GUI,而不要使用 "DOS box" sqlplus.exe!
操作系统语言环境 | NLS_LANG 值 |
---|---|
阿拉伯语(阿联酋) |
ARABIC_UNITED ARAB EMIRATES.AR8MSWIN1256 |
保加利亚语 |
BULGARIAN_BULGARIA.CL8MSWIN1251 |
加泰罗尼亚语 |
CATALAN_CATALONIA.WE8MSWIN1252 |
中文(中国) |
SIMPLIFIED CHINESE_CHINA.ZHS16GBK |
中文(中国台湾) |
TRADITIONAL CHINESE_TAIWAN.ZHT16MSWIN950 |
中文(香港 HKCS) |
TRADITIONAL CHINESE_HONG KONG.ZHT16HKSCS |
中文(香港 HKCS2001) |
TRADITIONAL CHINESE_HONG KONG.ZHT16HKSCS2001(10gR1 中新增) |
克罗地亚语 |
CROATIAN_CROATIA.EE8MSWIN1250 |
捷克语 |
CZECH_CZECH REPUBLIC.EE8MSWIN1250 |
丹麦语 |
DANISH_DENMARK.WE8MSWIN1252 |
荷兰语(荷兰) |
DUTCH_THE NETHERLANDS.WE8MSWIN1252 |
荷兰语(比利时) |
DUTCH_BELGIUM.WE8MSWIN1252 |
英语(英国) |
ENGLISH_UNITED KINGDOM.WE8MSWIN1252 |
英语(美国) |
AMERICAN_AMERICA.WE8MSWIN1252 |
爱沙尼亚语 |
ESTONIAN_ESTONIA.BLT8MSWIN1257 |
芬兰语 |
FINNISH_FINLAND.WE8MSWIN1252 |
法语(加拿大) |
CANADIAN FRENCH_CANADA.WE8MSWIN1252 |
法语(法国) |
FRENCH_FRANCE.WE8MSWIN1252 |
德语(德国) |
GERMAN_GERMANY.WE8MSWIN1252 |
希腊语 |
GREEK_GREECE.EL8MSWIN1253 |
希伯来语 |
HEBREW_ISRAEL.IW8MSWIN1255 |
保加利亚语 |
HUNGARIAN_HUNGARY.EE8MSWIN1250 |
冰岛语 |
ICELANDIC_ICELAND.WE8MSWIN1252 |
印度尼西亚语 |
INDONESIAN_INDONESIA.WE8MSWIN1252 |
意大利语(意大利) |
ITALIAN_ITALY.WE8MSWIN1252 |
日语 |
JAPANESE_JAPAN.JA16SJIS |
韩语 |
KOREAN_KOREA.KO16MSWIN949 |
拉脱维亚语 |
LATVIAN_LATVIA.BLT8MSWIN1257 |
立陶宛语 |
LITHUANIAN_LITHUANIA.BLT8MSWIN1257 |
挪威语 |
NORWEGIAN_NORWAY.WE8MSWIN1252 |
波兰语 |
POLISH_POLAND.EE8MSWIN1250 |
葡萄牙语(巴西) |
BRAZILIAN PORTUGUESE_BRAZIL.WE8MSWIN1252 |
葡萄牙语(葡萄牙) |
PORTUGUESE_PORTUGAL.WE8MSWIN1252 |
罗马尼亚语 |
ROMANIAN_ROMANIA.EE8MSWIN1250 |
俄语 |
RUSSIAN_CIS.CL8MSWIN1251 |
斯洛伐克语 |
SLOVAK_SLOVAKIA.EE8MSWIN1250 |
西班牙语(西班牙) |
SPANISH_SPAIN.WE8MSWIN1252 |
瑞典语 |
SWEDISH_SWEDEN.WE8MSWIN1252 |
泰语 |
THAI_THAILAND.TH8TISASCII |
西班牙语(墨西哥) |
MEXICAN SPANISH_MEXICO.WE8MSWIN1252 |
西班牙语(委内瑞拉) |
LATIN AMERICAN SPANISH_VENEZUELA.WE8MSWIN1252 |
土耳其语 |
TURKISH_TURKEY.TR8MSWIN1254 |
乌克兰语 |
UKRAINIAN_UKRAINE.CL8MSWIN1251 |
越南语 |
VIETNAMESE_VIETNAM.VN8MSWIN1258 |
注意:这是 DOS BOX SQL*Plus 版本 (sqlplus.exe/ plus80.exe / plus33.exe) 的正确设置
操作系统语言环境 | Oracle 客户端字符集(NLS_LANG 的第三部分) |
---|---|
阿拉伯语 |
AR8ASMO8X |
加泰罗尼亚语 |
WE8PC850 |
中文(中国) |
ZHS16GBK |
中文(中国台湾) |
ZHT16MSWIN950 |
捷克语 |
EE8PC852 |
丹麦语 |
WE8PC850 |
荷兰语 |
WE8PC850 |
英语(英国) |
WE8PC850 |
英语(美国) |
US8PC437 |
芬兰语 |
WE8PC850 |
法语 |
WE8PC850 |
德语 |
WE8PC850 |
希腊语 |
EL8PC737 |
希伯来语 |
IW8PC1507 |
保加利亚语 |
EE8PC852 |
意大利语 |
WE8PC850 |
日语 |
JA16SJIS |
韩语 |
KO16MSWIN949 |
挪威语 |
WE8PC850 |
波兰语 |
EE8PC852 |
葡萄牙语 |
WE8PC850 |
罗马尼亚语 |
EE8PC852 |
俄语 |
RU8PC866 |
斯洛伐克语 |
EE8PC852 |
斯洛文尼亚语 |
EE8PC852 |
西班牙语 |
WE8PC850 |
瑞典语 |
WE8PC850 |
土耳其语 |
TR8PC857 |
NLS_LANG 参数的 LANGUAGE 要素控制什么?
NLS_LANG 参数的语言要素控制一部分全球化支持特性的操作。它指定语言约定,例如 Oracle 消息、排序、日期名称和月份名称所使用的语言。每种受支持的语言均有一个唯一的名称,例如 AMERICAN、FRENCH 或 GERMAN。语言参数指定区域和字符集参数的默认值。如果未指定语言,则该值默认为 AMERICAN。
NLS_LANG 参数的 TERRITORY 要素控制什么?
NLS_LANG 参数的区域要素控制一部分全球化支持特性的操作。它指定区域约定,例如默认日期、货币和数字格式。每个受支持的区域均有一个唯一的名称,例如,AMERICA、FRANCE 或 CANADA。如果未指定区域,则将从语言值中得出该值。
要获得数据库中存储的字符真实数值,请使用 dump 命令:
该函数调用的语法如下所示:
DUMP( <value> [, <format> [, <offset> [, <length> ] ] ] )
其中:
value — 要显示的值
format 指一个编号,用于描述将以何种格式显示该值的各个字节:8 表示八进制,10 表示十进制,16 表示十六进制;0 到 16 之间的其他值表示十进制;大于 16 的值有点复杂,它表示:如果字节与可打印的 ASCII 代码相对应,则输出为 ASCII 字符;如果字节与 ASCII 控制代码相对应,则输出为 "^x",其他情况则输出为十六进制;格式编号加上 1000 表示在返回值中添加字符数据类型值的字符集信息。offset 指要显示的值的首个字节的偏移量;负值表示从末尾开始计数。length 指要显示的字节数。例如,
SQL> SELECT DUMP(col,1016)FROM table;
Typ=1 Len=39 CharacterSet=UTF8: 227,131,143,227,131,170
以 UTF8 编码返回包含 3 个日语字符的列值。例如,首个字符是 227(*255)+131。您可能需要将其转换为 UCS2,以便使用 Unicode Standard 代码页验证码位值。
在哪里进行字符转换?
考虑到性能方面的原因,转换操作通常在客户端完成。8.0.4 及之后的版本都是如此。如果数据库使用的是客户端不知道的字符集,则转换将在服务器端完成。8.1.6 及之后的版本都是如此。
Windows SQL*Plus 未能显示全部扩展字符,这是为何?
您看到黑色方块而不是字符,这可能是因为您没有为代码页定义正确的字体。字体是具有共同外观(字样、字符大小)的字形(源于"象形文字")的集合。操作系统使用字体将数值转换为屏幕上的图形表示。字体不一定一网无遗地包含您所使用的代码页中定义的全部数值的图形表示。因此有的时候,当您更改字体,而新字体无法表示特定符号时,屏幕上就会出现黑色方块。
Windows 的"字符集映射"实用程序可用于查看哪些字形是某种字体的一部分。
在 Windows 2000 和 XP 上:
开始菜单 -> 运行...
输入 "charmap" 后单击 "是"。
当我选择刚插入的字符时,为何出现了问号或倒置问号?
在客户端和数据库字符集之间转换字符时,要转换的字符应当包含在双方的字符集中。如果转换的目标字符集中不存在该字符,则会使用替代字符。某些字符集定义了特定的替代字符,以便在从其他特定字符集转换时可以使用,但如果未定义替代字符,则会使用默认的替代字符,例如 ?。系统无法从替代字符转换回原始字符。
只支持 iSQL*Plus 用作 UTF8/Unicode 客户端吗?
在 Windows OS 上是这样,在 Unix OS 上则不是。如果操作系统的语言环境为 UTF-8(例如,Linux 上的 en_US.UTF-8)且 NLS_LANG 字符集设置为 UTF8 或 AL32UTF8,则所有数据库实用程序(包括 Import、Export、SQL*Loader 和 SQL*Plus)都可以用作 UTF-8 客户端。
如何查看 UNIX 操作系统管理的码位?
要知道在 Unix 环境中为字符生成了哪个码位,请使用 "od" 命令:
$ echo "" | od -xc
您还可以使用 "echo" 命令查看与码位对应的字符,如下所示:
对于 Solaris、AIX、HP-UX 和 TRU64:
$echo '\0351'
对于 Linux:
$echo -e '\0351'
您可以使用 Locale Builder 或打印的代码页(参见以下链接)来验证您的本机代码页与 NLS_LANG 设置是否正确对应。如果有任何歧义,请使用以上命令获取多个字符的值。对于打印的代码页:
通常,NLS_LANG 需要与 MS-DOS OEM 代码页相匹配,在命令提示符下输入 chcp 可以得到该代码页:
C:\> chcp
Active code page: 437
C:\> set NLS_LANG=american_america.US8PC437
对于 SQL*Loader 之类的工具,您可以临时将 NLS_LANG 更改为要加载的文件 (FILE) 的字符集。更改 NLS_LANG 的另一种方法是使用 .ctl 文件中的 characterset 关键字,指定数据文件中数据的字符集。在此情况下,无论 NLS_LANG 客户端字符集如何设置,SQL*Loader 都会将数据文件中的数据解释为该字符集。下面是使用 utf16 的 .ctl 文件示例,此示例包含在演示区中:
-- Copyright (c) 2001 by Oracle Corporation
-- NAME
-- ulcase11.ctl - Load Data in the Unicode Character Set UTF-16
-- DESCRIPTION
-- Loads data in the Unicode character set UTF-16. The data is in little
-- Endean byte order. This means that depending on whether SQL*Loader is
-- running on a little Endean or a big Endean system, it will have to
-- byte swap the UTF-16 character data as necessary. This load uses
-- character length semantics, the default for the character set UTF-16.
--
-- This case study is modeled after case study 3 (ulcase3), which loads
-- variable length delimited (terminated and enclosed) data.
--
-- RETURNS
--
-- NOTES
-- None
-- MODIFIED (MM/DD/YY)
-- rpfau 02/06/01 - Merged rpfau_sqlldr_add_case_study_11
-- rpfau 01/30/01 - Creation
--
LOAD DATA
CHARACTERSET utf16
BYTEORDER little
INFILE ulcase11.dat
REPLACE
INTO TABLE EMP
FIELDS TERMINATED BY X'002c' OPTIONALLY ENCLOSED BY X'0022'
(empno integer external (5), ename, job, mgr,
hiredate DATE(20) "DD-Month-YYYY",
sal, comm,
deptno CHAR(5) TERMINATED BY ":",
projno,
loadseq SEQUENCE(MAX,1) )
在 Oracle9i 中,Export 实用程序始终使用数据库字符集导出用户数据,包括 Unicode 数据。Import 实用程序会自动将数据转换为目标数据库的字符集。
在 Oracle8i 中,Export 实用程序在导出用户数据时会将用户数据从数据库字符集转换为导出会话的 NLS_LANG 字符集。Import 实用程序首先会将数据转换为 Import 会话的 NLS_LANG 字符集,然后再将其转换为目标数据库的字符集。需要注意的是,导出和导入会话的 NLS_LANG 字符集应包含所有要迁移的字符。该字符集一般要么选用源数据库的字符集,要么选用目标数据库的字符集,并且对于 Export 和 Import 会话,该字符集通常都是相同的。对于会对导出文件造成一些限制的多字节字符集,尤其建议这么来选择。对于 Export 文件中包含的 DDL 语句,Oracle8i 与 NLS_LANG 字符集之间的转换在 Oracle9i 中进行。
服务器(或客户端)上的 NLS_LANG 对通过数据库链路进行的字符集转换没有影响。源数据库字符集与目标数据库字符集之间的双向转换将由 Oracle 来进行。
在 Windows 上有多个主目录时,NLS_LANG 并没有不同之处。具体采用的参数是可执行程序使用的 ORACLE_HOME 注册表项中指定的参数。如果在环境中设置了 NLS_LANG,则该设置将优先于注册表中的值,并且将应用于服务器/客户端上的所有 Oracle_Home。
您可以在以下注册表项中找到 NLS_LANG:
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE
或
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOMEx
Windows 上有两类工具/应用:
iSQL*Plus 是 Oracle 数据库中仅有的支持 Unicode 的客户端。
字符集是关于符号具有什么数值的约定。计算机并不认识 ‘A’ 或 ‘B’,它只是认识其操作系统 (OS) 或终端硬件(固件)中所使用的字符集中为该符号定义的(二进制)数值。计算机只能处理数值,这正是为何需要字符集的原因。字符集的例子包括 'ASCII'(一种老式 7 位字符集)、'ROMAN8’(UNIX 上的 8 位字符集)和 'UTF8’(一种多字节字符集)。
代码页是 Windows/DOS 编码方案的名称;对于 Oracle NLS 来说,您可以认为它与字符集相同。您还需要区分字体 (FONT) 与字符集/代码页。操作系统使用字体将数值转换为屏幕上的图形显示。举例来说,在 Windows 上的 Wingdings 字体中,‘A’ 在屏幕上并不会显示为 ‘A’,但对于 OS 而言,该数值表示的就是 ‘A’。因此,虽然在您看来它没有显示为 ‘A’,但在 Windows 看来,它就是 ‘A’ 并且会被保存为(或用作) ‘A’。
为了更好地理解上面的解释,请做个简单的实验,打开 MS Word,选择 Wingdings 字体,输入您的姓名(您将看到一些符号)并将其另存为 html 文件,然后使用记事本打开该 html 文件,您将在 <style> 部分看到字体的声明,并且将在 <body> 部分看到以纯文本格式显示的您的姓名且带有 style='font-family: Wingdings' 属性。如果在 Internet Explorer 或 Netscape 中打开该文件,您将再次看到 Wingdings 符号。发生变化的只是呈现形式,而不是数据本身。
对于特定字体,在您使用的代码页中定义的符号中,有些可能是不可见的符号,这只不过是因为该字体的创建者并未将所有符号的图形表示都囊括在该字体中。因此,当您更改字体时,有时会在屏幕上出现黑色方块。在 Windows 上,您可以使用'字符映射’工具查看字体中定义的所有符号。
主要有两个原因:
过去,由于没有官方标准,供应商为其硬件和软件定义了不同的字符集。
为了支持新的语言而定义了新的字符集。对于 8 位字符集,可支持的符号数量是有限的,因此不同的书面语言会有不同的字符集。
7 位字符集只能识别 128 个符号 (2^7)
8 位字符集能识别 256 个符号 (2^8)
Unicode (UTF-8) 是一个多字节字符集。Unicode 可以定义超过一百万个字符。有关 Unicode 的更多信息,请参阅 Oracle Unicode 数据库支持 (PDF) 白皮书
选择字符集的一个基本考虑因素是,确保它可以处理在当下及不确定的将来需要支持的任何语言。另一个不容忽视的因素是要考虑您希望利用哪些应用和技术来与数据库进行交互。请使用语言环境构建器(从 Oracle Database 9i 开始)查看为特定 Oracle 字符集定义的字符。
选择 Unicode 作为数据库字符集可确保为数据库中内置的以及基于数据库构建的一切事物奠定坚实的基础。Oracle 建议所有新系统部署均采用 Unicode。Oracle 还建议将旧系统迁移至 Unicode。如今,使用 Unicode 字符集部署系统将在可用性、兼容性和可扩展性方面获得许多优势。Oracle 将为您提供全面的支持,支持您更快速、更轻松地部署高性能系统,同时充分发挥 Unicode 的优势。即使您现在不需要支持多语言数据或对 Unicode 有任何需求,但从长远来看,Unicode 仍然是新系统的理想选择,最终将帮助您节省时间和资金,并为您带来竞争优势。
注:为免疑义,本网页所用以下术语专指以下含义: