`

oracle编码问题

 
阅读更多

跟数据库编码方式相关的有以下三个视图
--------------------------------------------------------------------------------
nls_database_parameters、nls_instance_parameters、nls_session_parameters 
--------------------------------------------------------------------------------

首先,我们看一下,这三个视图的sql定义:

sys> select view_name,text from dba_views where view_name like 'NLS%';  
      
VIEW_NAME                             TEXT  
------------------------- --------------------------------------------------  
NLS_SESSION_PARAMETERS    select substr(parameter, 1, 30),  
                                                      substr(value, 1, 40)  
                                               from v$nls_parameters  
                                               where parameter != 'NLS_CHARACTERSET' and  
                                               parameter != 'NLS_NCHAR_CHARACTERSET'
      
NLS_INSTANCE_PARAMETERS   select substr(upper(name), 1, 30),  
                                                      substr(value, 1, 40)  
                                               from v$system_parameter  
                                               where name like 'nls%'
      
      
VIEW_NAME                               TEXT  
------------------------- --------------------------------------------------  
NLS_DATABASE_PARAMETERS   select name,  
                                                 substr(value$, 1, 40)  
                                               from props$  
                                               where name like 'NLS%'

可以看出:

nls_database_parameters取值于props$, 即我们创建数据库时存储在数据库中的信息,这与环境变量和参数文件等是统统没有关系的。

nls_instance_parameters取值于v$system_parameter,下面让我们看一下v$system_parameter 在官方文档的定义:

V$SYSTEM_PARAMETER displays information about the initialization parameters that are currently in effect for the instance.

A new session inherits parameter values from the instance-wide values.

SYSTEM_PARAMETR展示的是作用于当前实力的初始化参数信息,而一个新的对话是继承实例范围的参数值的

 

 实例范围的参数值是不受环境变量的影响的,而对话范围的值受到环境变量影响

nls_session_parameters取值于V$NLS_PARAMETERS, 它的查询结果默认会从nls_instance_parameters继承,但是如果,我们在环境变量或者

通过ALTER SESSION 改变了nls的相关参数,则会覆盖默认值。

 

例如,当环境变量NLS_LANG=AMERICAN_AMERICA.AL32UTF8

SQL> select parameter,value from nls_session_parameters where parameter='NLS_LANGUAGE';  
      
PARAMETER                     VALUE  
------------------------------ ------------------------------  
NLS_LANGUAGE               AMERICAN

 

当环境变量NLS_LANG='SIMPLIFIED CHINESE_CHINA.AL32UTF8'

SQL> select parameter,value from nls_session_parameters where parameter='NLS_LANGUAGE';  
      
PARAMETER                     VALUE  
------------------------------ ------------------------------  
NLS_LANGUAGE               SIMPLIFIED CHINESE

 

 至于这几个视图作用可以看另一篇文章《查看oracle数据库编码及修改编码方法》

 

 

       接下来,要说清楚Oracle字符集的相关问题,则要先理清数据库运行过程中的架构以及在这个架构中的字符集设置及这些设置之间的关联关系。

         先画一张图看一下:

        

 

         在这个图中,为了说明问题,我们将服务器与客户端分开,客户端用应用程序比如sqlplus或者PL/SQL与服务端相连。

         服务端有两个字符集:服务端操作系统字符集(4)、服务端数据库字符集(1);

         客户端有一个字符集:客户端操作系统字符集(2);

         客户端有一个参数:操作系统参数NLS_LANG(3)。

         这三个字符集与一个参数中,有一个字符集对整个架构的运行没有影响,它就是服务端操作系统字符集(4),所以这个字符集将不再出现在我们的讨论过程中。

         为什么这个服务端操作系统字符集没有用呢?这是因为Oracle在存取字符时与客户端进行字符集确认与转码的过程是由Oracle数据库自身完成的,不需要经过Oracle数据库所在的服务器的帮助。具体的是怎么回事用以下例子说明一下。

         比如在Oracle数据库中有一个表,用如下语句创建:

         create table test(name varchar2(10));

         为了说明问题假定有这样的一个环境:服务器端Oracle数据库的字符集是UTF8,客户端操作系统字符集是ZHS16GBK,客户端NLS_LANG参数设置为ZHS16GBK。

那么从客户端应用程序(比如sqlplus)发出这样一条命令:

         insert into test (name) values('中国');

         首先,这里有一个字符串“中国”,客户端操作系统用ZHS16GBK对它进行编码,比如编成“D6D0B9FA”,并把它交给sqlplus程序,然后把它发送给Oracle数据库。

         接着,Oracle数据库收到一串编码“167219”,不是直接往数据库里一扔就完事的,它要问客户端操作系统:“请问你给我的这串代码是用什么格式编码的啊?”客户端操作系统怎么回答?它会这么回答:“编码格式请参照参数NLS_LANG”。Oracle数据库一看,NLS_LANG='ZHS16GBK',这个编码格式与Oracle数据库自身的编码格式“UTF8”不一样,然后就是Oracle数据库发挥自己专长的地方了,为什么呢?因为Oracle数据库有它自己的编码表,而且不是一张而是好多张编码表,它可以根据编码表对编码进行翻译和转码。这就好比Oracle数据库是一个翻译,它会好几国语言,牛人一个。像上面的这个情况,Oracle会把“D6D0B9FA这串代码拿过来,根据参数NLS_LANG查ZHS16GBK编码表,找到对应这串代码的字符“中国”,然后再到UTF8编码表中查“中国”对应的编码,比如查到的结果是“4E2D56FD”。

         最后,将转码之后的编码“4E2D56FD”存放到Oracle数据库中去。

         为了进一步说明问题,我们再执行一条语句:

         select name from test;

         首先,Oracle数据库会从数据库中取出一串代码“4E2D56FD”。

         接着,Oracle数据库不是直接把这串代码交给sqlplus程序,它会多问一句:“代码串我是取出来了,它是UTF8编码格式的,请问sqlplus,你希望要什么编码格式的?”,sqlplus仍然会很爽快地告诉Oracle数据库:“编码格式请继续参照参数NLS_LANG”。Oracle数据库一看,ZHS16GBK跟UTF8又不一样,所以先查UTF8编码表,找到编码“4E2D56FD”对应的字符“中国”,再查ZHS16GBK编码表,找到“中国”对应的编码“D6D0B9FA”,然后就是把最后得到的这串编码“D6D0B9FA”交给sqlplus程序。

         最后,sqlplus直接把得到的这串编码扔给客户端操作系统,而操作系统只有ZHS16GBK编码表,它不会问得到的这串编码是什么格式的,只会直接到ZHS16GBK编码表中去查“D6D0B9FA”对应的字符是什么,并把它交给应用程序显示出来。这个显示的结果是“中国”。

         以上就是一个完整的从客户端编码并经过Oracle数据库转码存入数据库,然后从数据库取出并转码交给客户端显示的实验。

         从以上过程我们可以得出以下一些结论:

         1.对Oracle数据库存取起作用的是这些:客户端操作系统字符集、客户端操作系统参数NLS_LANG、服务端数据库字符集。

         2.对Oracle数据库不起作用的是服务端操作系统字符集。

         3.客户端操作系统只有一张编码表,与客户端字符集对应。

         4.Oracle数据库的字符集只有一个,并且固定,一般不改变。

         5.存放在Oracle数据库中的字符串的编码格式只有一个,它就是数据库的字符集所对应的编码格式。

         6.Oracle数据库有很多张编码表,可以在数据存入时将其它编码格式的编码转换为数据库字符集指定的格式,取出时从数据库字符集指定的格式转换为其它编码格式。

         7.整个架构中的转码只发生在Oracle数据库边界上,其它地方没有。

         8.Oracle是根据客户端操作系统的参数NLS_LANG与自己的字符集进行对照来确定是否需要进行转码的。

         最最重要的结论出来了:

         9.Oracle数据库如何选择字符集?只有一个原则,那就是这个字符集要包含数据库运行过程中所能存入的数据字符,通常作为中国人我们选择ZHS16GBK,如果想再保险一点,选择AL32UTF8。

         10.服务器操作系统选择什么字符集?这个字符集与数据库字符集一点关系都没有,只跟谁有关?操作系统管理员!所以它的选择原则是,系统管理员想选择什么就选择什么。

         11.客户端操作系统选择什么字符集?我是中国人,我用中文操作系统,所以我选择ZHS16GBK。建议中国人都选择ZHS16GBK。

         12.客户端操作系统参数NLS_LANG参数如何设置?这个只有一个设置方法,那就是与操作系统字符集相同。要不然会出问题的……

         最最最最重要的一句话:

         最好的,最不容易出字符集错误的就是:将数据库字符集、客户端字符集、客户端操作系统NLS_LANG参数三个地方作同样的设置。

 

分享到:
评论

相关推荐

    oracle乱码问题解决

    Oracle数据库在处理中文字符时可能出现乱码问题,这主要源于字符集设置的不匹配或配置不当。字符集是Oracle为了支持不同语言文字显示而设定的,对于中文汉字来说,常见的字符集包括ZHS16CGB231280、ZHS16GBK、US7...

    在64位系统下oracle数据库安装和oracle乱码问题

    以下将详细解释如何在64位系统上安装Oracle数据库以及如何解决可能出现的乱码问题。 首先,安装Oracle数据库分为四个主要步骤: 1. **安装Oracle数据库**:下载并安装适合64位系统的Oracle数据库软件,例如Oracle ...

    解决linux下oracle中文乱码问题,添加中文支持

    解决linux下oracle中文乱码问题,添加中文支持解决linux下oracle中文乱码问题,添加中文支持解决linux下oracle中文乱码问题,添加中文支持解决linux下oracle中文乱码问题,添加中文支持解决linux下oracle中文乱码...

    C#连接Oracle乱码及客户端dll

    本主题将详细探讨如何解决C#连接Oracle时出现的乱码问题以及涉及的dll文件。 首先,oci.dll、ocijdbc10.dll、ociw32.dll、oraocci10.dll和oraociei10.dll是Oracle数据访问组件,用于在不同平台上与Oracle数据库进行...

    linux安装oracle图形界面乱码问题.docx

    Linux 安装 Oracle 图形界面乱码问题解决方案 Linux 安装 Oracle 图形界面乱码问题是由于多种原因引起的,比如 Linux 操作系统的语言环境、Oracle 安装包的语言环境、Java 显示问题等。下面是解决这个问题的详细...

    oracle数据库乱码问题解决

    ### Oracle数据库乱码问题解析与解决方案 #### 一、Oracle数据库乱码问题概述 在使用Oracle数据库的过程中,可能会遇到字符显示异常的问题,通常被称为“乱码”。这种情况会影响到数据的正确读取与处理,进而影响...

    链接服务器-SQL Server连接Oracle(乱码配置,无需修改数据库编码)

    网上基本找不到,sqlserver2012版本链接oracle乱码问题解决实测版。

    oracle数据库中文乱码问题解决方案.docx

    Oracle数据库中文乱码问题解决方案 Oracle数据库中文乱码...Oracle数据库中文乱码问题的解决方案需要同时修改数据库服务器端和客户端的字符编码设置。通过正确的设置,可以确保中文字符在Oracle数据库中的正确显示。

    安装oracle中文乱码问题

    ### 安装Oracle时中文乱码问题解决方案 #### 背景介绍 在进行Oracle数据库安装的过程中,很多用户会遇到中文显示为乱码的问题。这一现象不仅降低了用户体验,还可能影响到系统的正常配置与管理。本文将详细介绍如何...

    oracle乱码解决功能!!!

    oracle乱码解决功能的重要性在于它能够解决汉字显示异常的问题,从而确保Oracle数据库的数据正确显示。同时,了解Oracle数据库的字符集设置和客户端的字符集设置对于解决汉字显示异常的问题非常重要。

    ORACLE数据库中文显示乱码问题的解决

    ORACLE数据库中文显示乱码问题的解决,系统中ORACLE数据库在安装后不能正确显示中文,而是显示为'???'等此类乱码。他人总结分析的内容,可以参考下。

    Oracle数据库乱码问题

    ### Oracle数据库US7ASCII字符集乱码问题解析 在日常的软件开发与维护工作中,我们时常会遇到数据库字符集导致的数据显示错误问题。本文将详细探讨Oracle数据库中使用US7ASCII字符集时出现的乱码问题及其解决方案。...

    oracle乱码?号改成中文 +环境配置

    ### Oracle乱码问题解析与解决方案 #### 一、Oracle乱码问题概述 在使用Oracle数据库的过程中,有时会遇到中文字符显示为乱码的情况,尤其是在不同的操作系统或者不同的客户端访问同一个数据库时更为常见。这种...

    SQL-SERVER-64位配置ORACLE连接-中文乱码问题

    ### SQL-SERVER-64位配置ORACLE连接-中文乱码问题 在IT行业中,不同数据库之间的连接配置是一项常见的任务,特别是在需要实现跨平台数据交换的场景下。本文将详细介绍如何解决64位系统下的SQL Server连接Oracle...

    ORACLE_CHAR_ToolS(ORACLE字符转换)

    总之,"ORACLE_CHAR_ToolS"是一套针对Oracle数据库字符编码问题的解决方案,通过它可以有效地识别和解决乱码问题,确保数据的准确性和一致性。对于处理跨语言、多编码环境的数据库管理员来说,这样的工具是十分宝贵...

    linux 下oracle中文乱码字符集设置

    Linux 下的 Oracle 数据库在导入数据库时出现中文乱码问题,这是因为 Oracle 数据库中的字符集格式不支持中文。解决方法是通过修改字符集格式,将其修改成支持中文的格式,这样可以正常显示中文字符。 Oracle ...

    centos7下Oracle12中文乱码的问题

    替换oracle解压之后的database文件中的filegroup2文件 路径 :database/stage/Components/oracle.jdk/1.6.0.75.0/1/DataFiles

    Jdbc连接oracle远程数据库中文乱码解决

    Oracle数据库作为一款广泛应用的关系型数据库系统,其与Java应用程序的集成常常会遇到各种问题,其中之一就是字符编码导致的中文乱码问题。本文将深入探讨如何通过JDBC(Java Database Connectivity)连接Oracle远程...

    Oracle 10g 中文乱码问题

    ### Oracle 10g 中文乱码问题解析 #### 原因分析 在使用Oracle 10g数据库过程中,可能会遇到中文字符显示为乱码的情况。这种问题往往出现在数据库安装后,在尝试插入中文数据并查询时,数据显示为“?????”等形式...

    Linux上安装Oracle汉字乱码完整解决方案

    在Linux环境下安装Oracle数据库时,遇到汉字乱码问题是一个常见的挑战。这个问题主要出现在Oracle数据库的字符集设置与系统默认的字符集不匹配,或者缺少必要的中文字体。本文提供了一个完整的解决方案,旨在帮助...

Global site tag (gtag.js) - Google Analytics