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

浅析Oracle三层全球化支持(NLS)


转载
标签:

杂谈

分类:oracle
前言:
  1、NLS , ‘National Language Support (NLS)’ ,从概念我们看出这个参数实际上定义了数据库的存放数据的语言环境,当我们设定一种nls的时候实际上我们是为oracle在存放数据时指定了他的语种所特有的一些表达形式,比如我们选择chinese,那么它的中文字符如何存放,按什么规则排序,货币如何表示,日期格式也就被设定了。
        2、 Oracle对全球化(Global Support)有着全面的支持和解决方案,即用Oracle NLS架构来实现的
           OracleGlobal Support复杂的原因之一,就是Oracle的三层NLS体系。任何一个会话session在连接入数据库之后,都会面对三层NLS参数体系(即每一层都有一套自己的与其他层中同名的NLS参数变量集合。Database level有一个完备的NLS参数集合中各变量的值,这样很大层面上为后面两层提供了一个基础参数集合和存储标准,即当Instance Level里,用户没有为其NLS参数设置值时,则默认用Database level的给其赋值,当Session Level 里,用户没有为其NLS参数设置值时,则默认用Instance Level的给其赋值),分别为:DatabaseInstanceSession
    3、国际化(即Global Support的目的就是在于连接到同一个Oracle数据库服务端不同连接用户,都可以看到属于自己的Local化的结果(即同一个数据,在Oracle数据库服务端显示,和在客户端显示,可以按该数据不同的表示形式来显示)。比如,在我们在英文版的Oracle服务端(即Oracle服务端使用的NLS参数为英文字符集,具体说,
SQL> select * from nls_database_parameters;
 
PARAMETER                     VALUE
--------------------------------------------
NLS_LANGUAGE                  AMERICAN
NLS_TERRITORY                 AMERICA
NLS_CHARACTERSET              AL32UTF8(也可以是US7ASCII
调用时间函数而获得结果为“ 17-SEP-12 ”,
而在笔者的客户端系统(其使用的NLS参数为中文字符集的,即
SQL> select * from nls_session_parameters;
 
PARAMETER                     VALUE
------------------------------ -------------------------
NLS_LANGUAGE                  SIMPLIFIEDCHINESE
NLS_TERRITORY                 CHINA
NLS_CHARACTERSET              ZHS16GBK)中,
调用时间函数而获得结果显示为“ 17-9 -12 ”。
这都是 Oracle NLS 国际化所起到的作用。该例子的具体配置环境,见正文里的 1、环境介绍 部分。
   日期和数字类型的显示,带有很强烈的地区特性。比如,上述例子中,欧美格式“17-SEP-12”和我们更接受的“2012-9-17”就有很大的差距。Oracle将数据取值(即数据存储在oracle数据库中的二进制值)和显示分割开来,让session级别用户可以控制最终的显示。
    Instance Level配置是针对所有连接而言的。而国际化的目的就是在于不同连接用户,看到Local化的结果。因此,无论Instance Level进行何种的配置,最终很有可能都是被Session level的所覆盖。



正文:

作为一个成熟的商业数据库软件Oracle对全球化(Global Support)有着全面的支持和解决方案(即用Oracle NLS架构来实现的)。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国际化所起到的作用;

ü 软件显示语言;在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注册表内容为:

 

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

 

2、三层NLS体系

 

OracleGlobal Support复杂的原因之一,就是Oracle的三层NLS体系。任何一个会话session在连接入数据库之后,都会面对三层NLS参数体系(即每一层都有一套自己的与其他层中同名的NLS参数变量集合。Database level有一个完备的NLS参数集合中各变量的值,这样很大层面上为后面两层提供了一个基础参数集合和存储标准,即当Instance Level里,用户没有为其NLS参数设置值时,则默认用Database level的给其赋值,Session Level 里,用户没有为其NLS参数设置值时,则默认用Instance Level的给其赋值),分别为:DatabaseInstanceSession

 

ü Database Level NLS Parameter:数据库层面的NLS参数是在数据库创建的时候确定的一系列的参数。在创建数据库的时候,我们都可以通过OUIOracle 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 Level NLS Parameter确切的名字应该叫做 客户端 Level NLS Parameter。一个客户端可以有很多会话同时存在的),主要是通过一系列的环境变量来确定。Session LevelParameter是可以覆盖Instance Level的参数的;

 

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

 

3Database Level NLS Parameter

 

Database level参数是三层体系中最底层,这个层面的参数取值和Oracle数据库创建时的配置选项密切相关。我们在联入数据库时,可以通过几个视图来查看这个“根本性”的参数内容。

 

SQL> select * fromnls_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程序Oracle OUI 安装程序,即用于创建一个新的数据库的那个程序会根据所在服务器操作系统的配置内容,为我们选择出一个字符集(即创建数据库的界面里,选择字符集那一步,有个“操作系统默认字符集”选项)。

 

在从操作系统选择出字符集合的过程中,NLS_LANGLANG)环境变量起到很重要的作用(即“操作系统默认字符集”选项的值就是来自NLS_LANGLANG)环境变量中的.部分 操作系统的语言配置内容NLS_LANG是我们安装Oracle(即创建一个新的Oracle数据库)过程中,确定NLS参数的一个重要环境变量。

 

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

 

NLS_LANG=_.

 

 

如果我们需要在配置Oracle(即创建一个新的Oracle数据库)前就确定这些(Database Level )NLS参数内容,可以预先定义环境变量NLS_LANG(?)(创建一个新的Oracle数据库时,该数据库Database Level NLS参数中的NLS_LANGUAGENLS_TERRITORY NLS_CHARACTERSET三个变量的值来自客户端环境变量NLS_LANG的赋值Unix/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 * fromnls_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视图查看到这个内容(Session levelNLS参数来自客户端配置,故nls_session_parameters视图里的内容即来自客户端配置)。

 

SQL> select * fromnls_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 LevelParameter的默认值)。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上,可以添加注册表参数。

 


 

 

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,至关重要!


后记:

NLS_LANGUAGE影响oracle错误消息等在客户端中由oracle数据库(软件)服务端发来的要显示的消息(而非客户端本身所要显示的信息),再如splplus中的“表已创建、连接到”等显示的信息就是如此。NLS_LANGUAGE不影响表中(所有)数据的显示,具体的说,就是不影响表中varchar2/charnvarchar2/nchar字段的数据的显示(,还有显示日期类型的表字段)。

 

而表中varchar2/charnvarchar2/nchar字段的数据的显示由NLS_CHARACTERSETNLS_NCHAR_CHARACTERSET决定,即NLS_CHARACTERSETNLS_NCHAR_CHARACTERSET用于表示Oracle在保存varchar2/charnvarchar2/nchar字段时的保存类型。

 

NLS_DATA_LANGUAGE用来表示Oracle在显示日期类型的(的表字段里的)文字内容时,使用什么语言(的字符)。

 

至于NLS_LANGUAGE用什么字符集由oracle数据库软件决定,而NLS_CHARACTERSETNLS_NCHAR_CHARACTERSET则可以由oracle用户来自定义。

 

NLS参数最终被覆盖的值为oracle数据库(软件)服务端所用?

 

客户端的环境变量nls_lang 

NLS_LANG参数由以下部分组成:

NLS_LANG=_.

所以,客户端的nls_lang设置后会覆盖影响oracle数据库(软件)服务端nls架构模块功能程序中的session level的以下三个参数变量的数值:

 

NLS_LANGUAGE                  AMERICAN

NLS_TERRITORY                 AMERICA

NLS_CHARACTERSET

 

session level的NLS参数应该存放在各个UGA中。

 

客户端都是基于服务端程序提供的接口(来访问操作服务端程序的)而开发出来的,所以客户端是否需要某个环境变量是取决于服务端程序是否要用到该变量。故而,在其他非基于oracle数据库(软件)服务端程序提供的接口而开发出来的客户端是不需要用到环境变量nls_lang的。


除了NLS_CHARACTERSET变量外的NLS变量,都是以session level的该NLS参数值为准来控制显示结果。而NLS_CHARACTERSET变量则貌似要客户端和数据库端配合来控制显示结果?


NLS_LANGUAGE                  AMERICAN

NLS_TERRITORY                 AMERICA

NLS_CHARACTERSET

这三个参数是相互独立的,即其各自影响的数据不会有重合部分。

===============================================================================

NLS_LANGUAGE影响oracle错误消息等在客户端中由oracle数据库(软件)服务端发来的要显示的消息(而非客户端本身所要显示的信息),再如splplus中的“表已创建、连接到”等显示的信息就是如此。NLS_LANGUAGE不影响表中(所有)数据的显示,具体的说,就是不影响表中varchar2/charnvarchar2/nchar字段的数据的显示(,还有显示日期类型的表字段)。

 

而表中varchar2/charnvarchar2/nchar字段的数据的显示由NLS_CHARACTERSETNLS_NCHAR_CHARACTERSET决定,即NLS_CHARACTERSETNLS_NCHAR_CHARACTERSET用于表示Oracle在保存varchar2/charnvarchar2/nchar字段时的保存类型。

 

NLS_DATA_LANGUAGE用来表示Oracle在显示日期类型的(的表字段里的)文字内容时,使用什么语言(的字符)。

 

至于NLS_LANGUAGE用什么字符集由oracle数据库软件决定(根据NLS_LANGUAGE所指定的语言,oracle数据库软件服务端选择该语言下的一个字符集),而NLS_CHARACTERSETNLS_NCHAR_CHARACTERSET则可以由oracle用户来自定义。

 

NLS参数最终被覆盖的值为oracle数据库(软件)服务端所用?

 

客户端的环境变量nls_lang 

NLS_LANG参数由以下部分组成:

NLS_LANG=_.

所以,客户端的nls_lang设置后会覆盖影响oracle数据库(软件)服务端nls架构模块功能程序中的session level的以下三个参数变量的数值:

 

NLS_LANGUAGE                  AMERICAN

NLS_TERRITORY                 AMERICA

NLS_CHARACTERSET

 

session level的NLS参数应该存放在各个UGA中。

 

客户端都是基于服务端程序提供的接口(来访问操作服务端程序的)而开发出来的,所以客户端是否需要某个环境变量是取决于服务端程序是否要用到该变量。故而,在其他非基于oracle数据库(软件)服务端程序提供的接口而开发出来的客户端是不需要用到环境变量nls_lang的。

 

除了NLS_CHARACTERSET变量外的NLS变量,都是以session level的该NLS参数值为准来控制显示结果。而NLS_CHARACTERSET变量则貌似要客户端和数据库端配合来控制显示结果?

Session Level NLS Parameter和客户端nls环境变量集合(存在于注册表中)如nls_lang是两套不同的变量集合。这个从select * fromnls_session_parameters;中不存在NLS_CHARACTERSET一行,而客户端环境变量nls_lang里有NLS_CHARACTERSET,而可知。

Database Level NLS ParameterInstanceLevel NLS ParameterSession Level NLS Parameter间类似于类继承关系。NLS_CHARACTERSETDatabaseLevel NLS Parameter的私有成员变量,不可被Session Level NLS Parameter继承访问。当然,在Session Level里可以被继承访问的那些NLS Parameter的值在最终local化里起作用(,而不是Database Level或是Instance Level NLS Parameter的值)。

如果用户设置了某一客户端nls环境变量如nls_lang,则其值就会自动赋值给Session Level NLS Parameter里相应的NLS参数。

 

由于NLS_CHARACTERSET变量在Session Level里不存在的,所以客户端环境变量nls_lang里的NLS_CHARACTERSET是要和Database Level NLS Parameter NLS_CHARACTERSET一起配合共同起作用。

即凡是Session Level里不存在的变量,客户端环境变量里的该同名变量都是要和Database Level NLS Parameter该同名变量一起配合共同起作用。

凡是Session Level里存在的变量,则由其单独起作用。

 

 altersession set NLS_CHARACTERSET 提示 ora_000922missing orinvaild option

            说明NLS_CHARACTERSET不可在会话级别被修改。

 

 


 select userenv('language') from dual;

和selectsys_context('userenv','language') from dual;
  
都是显示 session Level NLS Parameter的值,其中就有NLS_CHARACTERSET的值,所以说明NLS_CHARACTERSETDatabase Level NLS Parameter的私有成员变量,被SessionLevel NLS Parameter继承却不可访问(即不可被修改)。

 selectuserenv('lang') from dual;显示 session Level NLS Parameter NLS_LANGUAGE的值。

 

 

NLS_LANGUAGE                  AMERICAN

NLS_TERRITORY                 AMERICA

NLS_CHARACTERSET

这三个参数是相互独立的,即其各自影响的数据不会有重合部分。

 

 

客户端nls_lang里的字符集,对在客户端里输入的SQL语句文本(的编码值),会将其当作是客户端nls_lang里的字符集编码的编码值来解释解析,而不会对其编码值进行转码为客户端nls_lang里的字符集编码的编码值。例如,输入的SQL语句文本的编码值(客户端字符集,作用的地方(?))采用的是ZHS16GBK字符集的,而客户端nls_lang里的字符集为AL32UTF8时,执行该SQL语句,提示ora911:无效字符,说明未转码。

 

客户端nls_lang里的字符集、客户端字符集是两个不同的变量,都是属于客户端的。

 

客户端环境变量nls_lang指定无效值,如写个无效的字符集名时,提示

ORA-12705:Cannot access NLS data files or invalid environment specified 



NLS_LANG值,则会根据所在服务器操作系统的配置内容,为我们选择出一个字符集


再论ORACLE的全球化支持(GLOBALIZATION)

=====================================

KOREAN_CHINA.KO16KSC5601
SIMPLIFIED CHINESE_CHINA.AL32UTF8
设计客户端nls_lang这个变量的作用是讲oracle服务端发来的所有字符串(包括错误消息字符串和表里字符串字段)的以服务端数据库字符集

编码的编码值转码为客户端字符集(狭义,即操作系统字符集)的编码值
故客户端nls_lang要和客户端字符集一致才好。客户端nls_lang要和客户端字符集间不转码,即设置为客户端字符集的客户端输出函数不转码

地显示以客户端nls_lang编码的
字符串为参数的值(从如下例子可知的:客户端nls_lang为ZHS16GBK,客户端字符集cmd 为代码页437时 如 表里的中文数据为乱码,而非?

字符,即可知道这里未发生转码)。

表里char数据类型的字符串字段 在 服务端数据库里以database级别的nls_charset字符集编码的
表里nchar数据类型的字符串字段 在 服务端数据库里以database级别的nls_ncharset字符集编码的
错误消息字符串等由session级别的nls_language决定,而nls_language值对应用的字符集由oracle服务端软件决定
oracle服务端发来的错误消息字符串  根据客户端nls_lang 转码
其他不变 服务端数据库字符集为ZHS16GBK 客户端字符集cmd GBK
客户端nls_lang
KOREAN_CHINA.KO16KSC5601
KOREAN_CHINA.AL32UTF8
显示乱码字符不一样,说明有转码

再如,
其他不变 服务端数据库字符集为ZHS16GBK 客户端字符集cmd GBK(即ZHS16GBK)
客户端nls_lang
SIMPLIFIED CHINESE_CHINA.US7ASCII
显示??字符,说明有转码(源字符集的字符不存在目标字符集里时,一般转码为?字符)

oracle服务端发来的错误消息字符串是否按
服务端数据库字符集编码的?
服务端数据库字符集为ZHS16GBK还是AL32UTF8
客户端nls_lang为ZHS16GBK时不乱码;
客户端nls_lang为AL32UTF8时乱码;
客户端字符集cmd一直是 GBK
这个例子还不能证明上述结论,因为
(客户端nls_lang为)ZHS16GBK 和(服务端数据库字符集为)AL32UTF8间(共有的字符)是可正确转码的,
而客户端nls_lang为AL32UTF8时客户端cmd的字符集为 GBK,故最后显示为乱码。

服务端数据库字符集为ZHS16GBK 客户端字符集cmd 韩文
客户端nls_lang
KOREAN_CHINA.KO16KSC5601
不乱码 说明oracle服务端发来的错误消息字符串不按
服务端数据库字符集编码的,而是
错误消息字符串等由session级别的nls_language决定,而nls_language值对应用的字符集由oracle服务端软件决定。


你可能感兴趣的:(oracle字符集问题)