作为一个成熟的商业数据库软件,Oracle对全球化(Global Support)有着全面的支持和解决方案。Oracle在国际化支持方面主要体现在几个方面:
ü 全球化字符集支持;目前,Oracle支持所有主流的字符集样式。通过NLS_CHARACTER和NLS_NCHAR_CHARACTER指定的字符集可以支持全世界绝大多数语言文字的存储。Oracle推荐的字符集样式为AL32UTF8,也就是通常我们所见的UTF-8编码格式;
ü 全球化时区Timezone支持;全球化一个重要问题就是时区显示和保存问题。不同时区的用户同时向一个数据库插入数据,其时间先后是不可能回避的问题。同时,当非本地时区日期类型显示的时候,时区如何进行转换。Oracle在这个问题上提供了两个类型:Timestamp with timezone和Timestamp with local timezone,方便的解决了这些问题;
ü 日期和数字格式显示问题;日期和数字类型的显示,带有很强烈的地区特性。比如,欧美格式“17-SEP-12”和我们更接受的“2012-9-17”就有很大的差距。Oracle将数据取值和显示分割开来,让session级别用户可以控制最终的显示;
ü 软件显示语言;在Oracle软件和一些显示中,很多的字符和软件输出就带有语言特性。比如,我们在英文版的Oracle服务端调用时间函数,获得“17-SEP-12”,而在笔者的客户端系统中,就显示为“17-9月 -12”。这都是Oracle NLS国际化所起到的作用;
NLS是一套覆盖面广、内容庞杂的知识体系。笔者计划在接下来用一个系列来分析这个体系。本次,我们只是给NLS一个简单的体系介绍:Oracle的三层NLS体系关系和优先级配置。
1、环境介绍
笔者选择Oracle 11gR2进行试验。
SQL> select * from v$version;
BANNER
---------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 – Production
服务器是 Red Hat 5.3 32bit ,安装时选择的是英文,美语。
[oracle@bspdev ~]$ uname -a
Linux bspdev.localdomain 2.6.18-308.el5 #1 SMP Tue Feb 21 20:05:41 EST 2012 i686 i686 i386 GNU/Linux
查看Linux系统支持语言和时区:
[oracle@bspdev ~]$ cat /etc/sysconfig/i18n
LANG="en_US.UTF-8"
SYSFONT="latarcyrheb-sun16"
[oracle@bspdev sysconfig]$ pwd
/etc/sysconfig
[oracle@bspdev sysconfig]$ cat clock
# The ZONE parameter is only evaluated by system-config-date.
# The timezone of the system is defined by the contents of /etc/localtime.
ZONE="Asia/Shanghai"
UTC=true
ARC=false
客户端使用的是中文的Windows 7,对应的Oracle注册表内容为:
NLS_LANG参数告知本地所在地中国、中文语言和ZHS16GBK字符集。
2、三层NLS体系
Oracle的Global Support复杂的原因之一,就是Oracle的三层NLS体系。任何一个会话session在连接入数据库之后,都会面对三层NLS参数体系,分别为:Database、Instance和Session。
ü Database Level NLS Parameter:数据库层面的NLS参数是在数据库创建的时候确定的一系列的参数。在创建数据库的时候,我们都可以通过OUI或者responseFile进行配置。大部分Database Level NLS Parameter都是不可以改变,或者不能轻易改变的,如CharacterSet;
ü Instance Level NLS Parameter:在数据库运行过程中,一些NLS参数是通过Spfile/Pfile参数文件进行配置,并且可以对Database Level NLS进行一定的覆盖修改。如果Instance Level与Database Level的发生冲突,以Instance Level覆盖Database Level的配置;
ü Session Level NLS Parameter:这个层面是和用户连接效果最直接的层面。用户使用的NLS参数很多都是取到这个层面的参数。Session Level Parameter来自客户端配置内容,主要是通过一系列的环境变量来确定。Session Level的Parameter是可以覆盖Instance Level的参数的;
下面我们分别来介绍几个层面参数中的重要内容。
3、Database Level NLS Parameter
Database level参数是三层体系中最底层,这个层面的参数取值和Oracle数据库创建时的配置选项密切相关。我们在联入数据库时,可以通过几个视图来查看这个“根本性”的参数内容。
SQL> select * from nls_database_parameters;
PARAMETER VALUE
------------------------------ ---------------------------------------
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY AMERICA
NLS_NUMERIC_CHARACTERS .,
NLS_CHARACTERSET AL32UTF8
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE AMERICAN
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY $
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_RDBMS_VERSION 11.2.0.1.0
20 rows selected
nls_xxx_parameters系列视图非常重要,特别是在我们配置NLS参数的过程中。我们可以通过nls_database_parameters查看到Database的NLS参数。
NLS_CHARACTERSET和NLS_NCHAR_CHARACTERSET用于表示Oracle在保存varchar2/char和nvarchar2/nchar字段时的保存类型。从Oracle官方推荐的角度,我们设置AL32UTF8字符集作为数据库字符集,基本上就可以应对常见的字符文字类型了。
在安装程序OUI运行是,AL32UTF8往往不是默认选项。Oracle OUI程序会根据所在服务器操作系统的配置内容,为我们选择出一个字符集。
在从操作系统选择出字符集合的过程中,NLS_LANG(LANG)环境变量起到很重要的作用。NLS_LANG是我们安装Oracle过程中,确定NLS参数的一个重要环境变量。
根据Oracle的要求,NLS_LANG中包括了Oracle所在地域Territory、语言Language和字符集CharacterSet三部分内容。
NLS_LANG=_.
如果我们需要在配置Oracle前就确定这些参数内容,可以预先定义环境变量NLS_LANG。Unix/Linux环境下,可以配置在Oracle用户的.bash_profile中。而Windows环境下,这个参数要配置在注册表中。
此外,NLS_DATA_LANGUAGE用来表示Oracle在显示日期类型的文字内容时,使用什么语言。
Database Level NLS parameter是非常基本的,起作用的范围主要数据库内部。另一方面,Database Level NLS Parameter是作为Instance Level配置的默认基础值。在安装数据库后,我们基本不能、也不会对database level的NLS参数进行修改。我们的“手脚”只能在Instance和Session level进行。
3、Instance level NLS Parameter
Instance Level NLS parameter,就是我们可以控制的领域了。Instance参数主要来自于参数文件SPFILE/PFILE。我们可以通过nls_instance_parameters来查看这个层面的参数配置。
SQL> select * from nls_instance_parameters;
PARAMETER VALUE
------------------------------ -------------------------
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_SORT
NLS_DATE_LANGUAGE
NLS_DATE_FORMAT
NLS_CURRENCY
NLS_NUMERIC_CHARACTERS
NLS_ISO_CURRENCY
NLS_CALENDAR
NLS_TIME_FORMAT
NLS_TIMESTAMP_FORMAT
NLS_TIME_TZ_FORMAT
NLS_TIMESTAMP_TZ_FORMAT
NLS_DUAL_CURRENCY
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
17 rows selected
相对于database level,Instance level的参数数量是很少的。通常我们不会在参数文件层面进行NLS参数配置,保持Database Level的默认配置就可以了。
这样的原因是Instance Level配置是针对所有连接而言的。而国际化的目的就是在于不同连接用户,看到Local化的结果。无论Instance Level进行何种的配置,最终很有可能都是被Session level的所覆盖。
Database level之所以会有完备的NLS参数,很大层面上是提供了一个基础参数集合和存储标准。NLS的重头在session层面。
4、Session Level NLS Parameter
Session Level的NLS参数是和用户最直接交互的部分。我们可以通过nls_session_parameters视图查看到这个内容。
SQL> select * from nls_session_parameters;
PARAMETER VALUE
------------------------------ -------------------------
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_CURRENCY ¥
NLS_ISO_CURRENCY CHINA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE SIMPLIFIED CHINESE
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY ¥
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
17 rows selected
session level的参数是影响最终我们看到NLS结果的控制因素。Session level的NLS参数来自客户端配置。对Windows而言,就是我们注册表中关于NLS_LANG等一系列的环境变量。对Unix/Linux而言,就是我们配置在.bash_profile文件中定义的相应内容。
注意,NLS_LANG本身包括的内容很多。NLS_LANG包括了客户端地域、语言和字符集信息。地域间接影响到时区,语言会影响到显示语言。而字符集更是影响数据从服务器传递过来客户端后,进行的转换策略。
在三层NLS体系下,Session Level的Parameter起到最后的决定作用。如果Session level没有配置,Oracle会选择Instance乃至Database的配置。Session Level的配置会覆盖Instance level的取值。
我们可以根据自己的情况,动态的进行调节session level nls parameter。如果我们只是希望NLS暂时性修改,可以选择alter session set语句进行参数切换。
SQL> select sysdate from dual;
SYSDATE
--------------
17-9月 -12
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
会话已更改。
SQL> select sysdate from dual;
SYSDATE
-------------------
2012-09-17 06:23:58
如果希望长期的修改,可以考虑在环境变量的层面上修改参数。在windows上,可以添加注册表参数。
SQL> select * from nls_session_parameters where parameter='NLS_DATE_FORMAT';
PARAMETER VALUE
------------------------------ -------------------------
NLS_DATE_FORMAT yyyy-mm-dd hh24:mi:ss
SQL> conn sys/oracle@wilson as sysdba
已连接。
SQL> select sysdate from dual;
SYSDATE
-------------------
2012-09-17 06:29:02
5、结论
NLS参数对我们开发和使用Oracle,至关重要!
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17203031/viewspace-743716/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/17203031/viewspace-743716/