暂无图片
暂无图片
暂无图片
暂无图片
暂无图片
搞懂oracle字符集
949
7页
7次
2019-07-24
5墨值下载
oracle
oracle
oracle
oracle
字符
作为一个 ORACLE DBA, 在工作中会经常处理由于字符集产生的一些问题。 是当真
想写一些 这方面的 东西时,突然又没有了头绪。了半天呆,是决定用两个字符集方
的例子作为切入点,不失为一个头绪,不定在实验的过程中,题就会一个接着一个
浮现出来。
现在,让我们切入正题。
我用的数据库是 oracle10.2.0.3, 数据库字符集是 al32utf8
客户端就是同一台机器的 windows xp.
下面是演示的例子:
SQL> drop table test purge;
Table dropped.
SQL> create table test(col1 number(1),col2 varchar2(10));
Table created.
--session 1 设置 zhs16gbk (修 nls_lang 项的 characterset
zhs16gbk 向表中插入两个中文字符。
SQL> insert into test values(1,' 中国 '); --1 session 1 的标记
1 row created.
SQL> commit;
Commit complete.
--session 2 设置客户端字符集 al32utf8 (修改注册表 nls_lang 项的 characterset al32utf8
与数据库字符集相同。 向表中插入两个和 session 1 相同的中文字符。
SQL> insert into test values(2,' 中国 '); --2 session 2 的标记
1 row created.
SQL> commit;
Commit complete.
--session 1
SQL> select * from test;
COL1 COL2
---------- --------------------
2 ??
1 中国
--session 2
SQL> select * from test;
COL1 COL2
---------- ----------
2 中国
1 󳴆
session 1 session 2 的结果中可以看到,相同的字符(注意,我指的是我们看到的
显示为相同的字符) 在不同的字符集输入环境下,显示成了乱码。
zhs16gbk 字符集的客户端,我们看到了 utf8 字符集客户端输入的相同的中文变成了乱
-->col1=2 col2 字段
utf8 字符集客户端,我们看到 zhs16gbk 字符集的客户端输入的中文变成了另外的字符
-->col1=1 col2 字段
从这个例子里, 们好像感觉到出了什么问题, 可能会联想起现实环境中出现的乱码问
问题似乎有了思路, ok ,让我们继续把实验做下去:
--session 1 (或者 session 2 ,在这里无所谓)
SQL> select col1,dump(col2,1016) from test;
COL1
----------
DUMP(COL2,1016)
--------------------------------------------------------------------------------
2
Ty p=1 Len=4 CharacterSet=AL32UTF8: d6,d0,b9,fa
1
Ty p=1 Len=6 CharacterSet=AL32UTF8: e4,b8,ad,e5,9b,bd
我们使用了 dump 函数,结果看起来很明显了,两个完全相同的字符,在不同的字符集
环境下,在数据库中存储成了不同的编码。
对于 ZHS16GBK 的字符集客户端输入的字符 " 中国 "
AL32UTF8 使用了 3 个字节来分
存储一个字符,即:
--e4,b8,ad
--e5,9b,bd
我们也可以分别对这个字符进行验证:
--session 1
SQL> select dump(' ',1016) from dual;
DUMP(' ',16)
--------------------------------------------
Ty p=96 Len=3 CharacterSet=AL32UTF8: e4,b8,ad -- 字符 和上面直接从数据库中读取存储
字符编码一致。
SQL> select dump(' ',1016) from dual;
DUMP(' ',16)
--------------------------------------------
Ty p=96 Len=3CharacterSet=AL32UTF8: e5,9b,bd -- 字符 ,和上面直接从数据库中读取存储的
字符编码一致。
如果使用 session 2 直接对着两个字符进行测试,一样会得到相同的结果(笔者已经做
过测试,这里为了避免冗长,删掉了) .
让我们重新来理一下思路,并提出几个问题:
1 :为什么显示为相同的字符,存储到数据库中却变成了不同的编码?
2 :我们在向数据库中插入数据的时候, oracle 究竟做了些什么?
3 :操作系统字符集,客户端字符集,数据库字符集究竟是什么关系?
带着这些疑惑,让我们接着做实验,所有的疑团和猜测都会在试验中得以验证。
我的思路是,先取得测试环境的相关参数。
1 windows 字符集 (codepage)
我们使用 chcp 命令来获得 windows 使用的字符集
c:\chcp
活动的代码页
:
936
通过 oracle 的官方文档阅读,我们可以将它等同 ZHS16GBK 字符集(在安装 oracle
时, oracle 会找到安装平台的字符集,并默认将对应的字符集设置成与它相同,在这里,
据库默认的字符集本身应该是 ZHS16GBK, 但我强制将它修改为 AL32UTF8
所以现在我们可以认为,我们使用的操作系统是 ZHS16GBk 字符集,那么我们在这个
环境下输入的字符(也可以说是显示的字符,用的就是这个字符集的编码)
让我们继续讨论问题。
我们现在要讨论一下客户端字符集究竟是用来做什么的。
我们知道,多字符集都有自己的编码方式,换句话说,同的字符,在不同的字符
里对应的编码可能是不一样的。
客户端的字符集就是为了让数据库知道我们传递过去的字符是属于那种字符集, 便
oracle 在存储字符时做相应的编码映射。
of 7
5墨值下载
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文档的来源(墨天轮),文档链接,文档作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。