欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

【不错】浅析Oracle三层全球化支持(NLS)

程序员文章站 2022-05-20 23:48:21
...

作为一个成熟的商业 数据库 软件 , Oracle 对全球化( Global Support )有着全面的支持和解决方案。 Oracle 在国际化支持方面主要体现在几个方面: ü 全球化字符集支持;目前, Oracle 支持所有主流的字符集样式。通过 NLS_CHARACTER 和 NLS_NCHAR_CHARACT

作为一个成熟的商业数据库软件Oracle对全球化(Global Support)有着全面的支持和解决方案。Oracle在国际化支持方面主要体现在几个方面:

ü 全球化字符集支持;目前,Oracle支持所有主流的字符集样式。通过NLS_CHARACTERNLS_NCHAR_CHARACTER指定的字符集可以支持全世界绝大多数语言文字的存储。Oracle推荐的字符集样式为AL32UTF8,也就是通常我们所见的UTF-8编码格式;

ü 全球化时区Timezone支持;全球化一个重要问题就是时区显示和保存问题。不同时区的用户同时向一个数据库插入数据,其时间先后是不可能回避的问题。同时,当非本地时区日期类型显示的时候,时区如何进行转换。Oracle在这个问题上提供了两个类型:Timestamp with timezoneTimestamp 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 EnterpriseEdition 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:41EST 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 isonly 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注册表内容为:

【不错】浅析Oracle三层全球化支持(NLS)

NLS_LANG参数告知本地所在地中国、中文语言和ZHS16GBK字符集。

2、三层NLS体系

OracleGlobal Support复杂的原因之一,就是Oracle的三层NLS体系。任何一个会话session在连接入数据库之后,都会面对三层NLS参数体系,分别为:DatabaseInstanceSession

ü Database Level NLS Parameter:数据库层面的NLS参数是在数据库创建的时候确定的一系列的参数。在创建数据库的时候,我们都可以通过OUI或者responseFile进行配置。大部分Database Level NLS Parameter都是不可以改变,或者不能轻易改变的,如CharacterSet

ü Instance Level NLS Parameter:在数据库运行过程中,一些NLS参数是通过Spfile/Pfile参数文件进行配置,并且可以对Database Level NLS进行一定的覆盖修改。如果Instance LevelDatabase Level的发生冲突,以Instance Level覆盖Database Level的配置;

ü Session Level NLS Parameter:这个层面是和用户连接效果最直接的层面。用户使用的NLS参数很多都是取到这个层面的参数。Session Level Parameter来自客户端配置内容,主要是通过一系列的环境变量来确定。Session LevelParameter是可以覆盖Instance Level的参数的;

下面我们分别来介绍几个层面参数中的重要内容。

3Database 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.SSXFFAM

NLS_TIMESTAMP_FORMAT DD-MON-RRHH.MI.SSXFF AM

NLS_TIME_TZ_FORMAT HH.MI.SSXFFAM TZR

NLS_TIMESTAMP_TZ_FORMAT DD-MON-RRHH.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查看到DatabaseNLS参数。

NLS_CHARACTERSETNLS_NCHAR_CHARACTERSET用于表示Oracle在保存varchar2/charnvarchar2/nchar字段时的保存类型。从Oracle官方推荐的角度,我们设置AL32UTF8字符集作为数据库字符集,基本上就可以应对常见的字符文字类型了。

在安装程序OUI运行是,AL32UTF8往往不是默认选项。Oracle OUI程序会根据所在服务器操作系统的配置内容,为我们选择出一个字符集。

在从操作系统选择出字符集合的过程中,NLS_LANGLANG)环境变量起到很重要的作用。NLS_LANG是我们安装Oracle过程中,确定NLS参数的一个重要环境变量。

根据Oracle的要求,NLS_LANG中包括了Oracle所在地域Territory、语言Language和字符集CharacterSet三部分内容。

NLS_LANG=_.

如果我们需要在配置Oracle前就确定这些参数内容,可以预先定义环境变量NLS_LANGUnix/Linux环境下,可以配置在Oracle用户的.bash_profile中。而Windows环境下,这个参数要配置在注册表中。

此外,NLS_DATA_LANGUAGE用来表示Oracle在显示日期类型的文字内容时,使用什么语言。

Database Level NLS parameter是非常基本的,起作用的范围主要数据库内部。另一方面,Database Level NLS Parameter是作为Instance Level配置的默认基础值。在安装数据库后,我们基本不能、也不会对database levelNLS参数进行修改。我们的“手脚”只能在InstanceSession level进行。

3Instance 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 levelInstance level的参数数量是很少的。通常我们不会在参数文件层面进行NLS参数配置,保持Database Level的默认配置就可以了。

这样的原因是Instance Level配置是针对所有连接而言的。而国际化的目的就是在于不同连接用户,看到Local化的结果。无论Instance Level进行何种的配置,最终很有可能都是被Session level的所覆盖。

Database level之所以会有完备的NLS参数,很大层面上是提供了一个基础参数集合和存储标准。NLS的重头在session层面。

4Session Level NLS Parameter

Session LevelNLS参数是和用户最直接交互的部分。我们可以通过nls_session_parameters视图查看到这个内容。

SQL> select * from nls_session_parameters;

PARAMETER VALUE

------------------------------ -------------------------

NLS_LANGUAGE SIMPLIFIEDCHINESE

NLS_TERRITORY CHINA

NLS_CURRENCY

NLS_ISO_CURRENCY CHINA

NLS_NUMERIC_CHARACTERS .,

NLS_CALENDAR GREGORIAN

NLS_DATE_FORMAT DD-MON-RR

NLS_DATE_LANGUAGE SIMPLIFIEDCHINESE

NLS_SORT BINARY

NLS_TIME_FORMAT HH.MI.SSXFFAM

NLS_TIMESTAMP_FORMAT DD-MON-RRHH.MI.SSXFF AM

NLS_TIME_TZ_FORMAT HH.MI.SSXFFAM TZR

NLS_TIMESTAMP_TZ_FORMAT DD-MON-RRHH.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 levelNLS参数来自客户端配置。对Windows而言,就是我们注册表中关于NLS_LANG等一系列的环境变量。对Unix/Linux而言,就是我们配置在.bash_profile文件中定义的相应内容。

注意,NLS_LANG本身包括的内容很多。NLS_LANG包括了客户端地域、语言和字符集信息。地域间接影响到时区,语言会影响到显示语言。而字符集更是影响数据从服务器传递过来客户端后,进行的转换策略。

在三层NLS体系下,Session LevelParameter起到最后的决定作用。如果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-ddhh24:mi:ss';

会话已更改。

SQL> select sysdate from dual;

SYSDATE

-------------------

2012-09-17 06:23:58

如果希望长期的修改,可以考虑在环境变量的层面上修改参数。在windows上,可以添加注册表参数。

【不错】浅析Oracle三层全球化支持(NLS)


SQL> select * from nls_session_parameters whereparameter='NLS_DATE_FORMAT';

PARAMETER VALUE

------------------------------ -------------------------

NLS_DATE_FORMAT yyyy-mm-ddhh24:mi:ss

SQL> conn sys/oracle@wilson as sysdba

已连接。

SQL> select sysdate from dual;

SYSDATE

-------------------

2012-09-17 06:29:02

5、结论

NLS参数对我们开发和使用Oracle,至关重要!