您好,欢迎来到尚佳旅游分享网。
搜索
您的当前位置:首页Oracle之dmp导入/导出、数据库操作等过程中的字符集问题

Oracle之dmp导入/导出、数据库操作等过程中的字符集问题

来源:尚佳旅游分享网

Oracle之 dmp导入/导出、数据库操作等过程中的字符集问题 原文标题:Oracle_字符集问题(数据库与客户端字符集关联关系) //时间:2013-07-07 //作者:shm //描述:本文主要记录了Oracle数据库的字符集问题,也涉及作为服务器操作系统的CentOS或者Windows的

Oracle之 dmp导入/导出、数据库操作等过程中的字符集问题



原文标题:Oracle_字符集问题(数据库与客户端字符集关联关系)


//时间:2013-07-07

//作者:shm

//描述:本文主要记录了Oracle数据库的字符集问题,也涉及作为服务器操作系统的CentOS或者Windows的字符集与Oracle字符集之间的关联关系。

Oracle的字符集,这个问题的提出是因为两个原因:一是工作中遇到一个DMP文件需要恢复到数据库中去,而这个DMP文件的字符集是US7ASCII,第二个原因是一直在学习CentOS,在这个系统上安装Oracle已经能成功,但是被中文英文系统字符集等问题搞得有点头大。所以又回头翻了翻盖国强的书、看了看尚观的视频,终于有点心得,所以就写下了这篇算是笔记的文章。

Oracle数据库的字符集问题不算是大问题,但也是一个头疼的问题。这是因为有这么三个原因:一是Oracle数据库在安装时指定好字符集之后一般不能更改,二是字符集问题涉及服务器与客户端之间的存取问题,三是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对它进行编码,比如编成“167219”,并把它交给sqlplus程序,然后把它发送给Oracle数据库。

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

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

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

select name from test;

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

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

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

Copyright © 2019- shangjiatang.cn 版权所有 湘ICP备2022005869号-4

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务