关于UTF8字符集的话题
作者:八神 | 分类: 大话技术 | 标签: 大话技术 | 日期:2008-02-20
UTF8字符集几乎包含了世界上所有的语言字符,应用程序需要在同一页面显示多种语言时,我们往往会选择将数据库的字符集定为UTF8,然而,这个字符集在使用的时候,会有一些困惑
1.客户段NLS_LANG与数据库一致的时候,数据存取不需要转码,所以多语言问题只要NLS_LANG=UTF8就搞定
NLS_LANG保持与数据库一致,oracle客户段软件确实不会对数据进行转码,但他更不会关心你输入的数据格式是否真的和数据库匹配,比如我windows的语言区域是简体中文,对应的字节编码是zhs16gbk,那么他就会把zhs16gbk编码原封不动的存入utf8数据库,明明想要馒头的你却给我砖头,但我还是通吃,只不过日后你再想把这部分东西当馒头用,就会遇到麻烦
[oracle@japdev_new ~]#export NLS_LANG=AMERICAN_AMERICA.UTF8
japan@JAPDEV>select value from v$nls_parameters where PARAMETER = ‘NLS_CHARACTERSET’;
VALUE
—————————————————————-
UTF8
japan@JAPDEV>insert into myword values(’垃圾’);
1 row created.
japan@JAPDEV>select dump(word) from myword;
DUMP(WORD)
——————————————————————————————————————————————————
Typ=1 Len=4: 192,172,187,248
1 row selected.
现在找个zhs16gbk的数据库,存入同样的数据
oracps@:/home/oracps>export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
SQL> select value from v$nls_parameters where PARAMETER = ‘NLS_CHARACTERSET’;
VALUE
—————————————————————-
ZHS16GBK
SQL> insert into myword values(’垃圾’);
1 row created.
SQL> select dump(word) from myword;
DUMP(WORD)
——————————————————————————–
Typ=1 Len=4: 192,172,187,248
可以看到两个的编码都是ZHS16GBK,因为我们的WINDOWS直接输入字符,他本身不是UTF8格式的,这个时候你必须告诉ORACLE,你在用他的子集与他交互,转码是必须的
[oracle@japdev_new ~]#export NLS_LANG=AMERICAN_AMERICA.ZHS16GBKjapan@JAPDEV>select value from v$nls_parameters where PARAMETER = ‘NLS_CHARACTERSET’;
VALUE
———————————————————————————–
UTF8
japan@JAPDEV>insert into myword values(’垃圾’);
japan@JAPDEV>select dump(word) from myword;
Typ=1 Len=4: 192,172,187,248
Typ=1 Len=6: 229,158,131,229,156,190
第2条数据才是正确的UTF8编码,第一条数据是完全把数据库当存储在用,所以在应用程序与UTF8数据库交互时,应该保持一个原则,如果你的程序能够提供UTF8格式的编码,那么你的程序环境就与数据库保持一致,进去,出来,展现都没什么问题,如果程序不能提供UTF8编码,那么就告诉ORACLE,让他自己去转码,此时你应该明确输入编码的格式,用这个子集与oracle去交互
2.ORA-01756: quoted string not properly terminated
[oracle@japdev_new ~]#export NLS_LANG=AMERICAN_AMERICA.UTF8
japan@JAPDEV>select value from v$nls_parameters where PARAMETER = ‘NLS_CHARACTERSET’;
VALUE
—————————————————————-
UTF8
japan@JAPDEV>insert into myword values(’收费’);
ERROR:
ORA-01756: quoted string not properly terminated
此时并没有语法错误,而是SQL解析器在解析你的语句出了问题,按照上面的思路,NLS_LANG是一致的,解吸器会认为你的数据源就是UTF8,他也会按照UTF8的规则来读取’收费’两个字,而传过去的字节流来源于我的windows,是zhs16gbk的,双字节,但UTF8里面的汉字一般是3字节,这样很容易导致ORACLE把最后的一个单引号当成一个字节也解析进去,最后就报了语法错误



意犹未尽啊
fcp @ February 21, 2008 |
字符集的问题确实比较头疼。
还好,经过一周的努力,总算一切都归为平静了。
vogts @ February 21, 2008 |
复杂
yumianfeilong @ February 22, 2008 |
(⊙ˍ⊙)>﹏<
环形变压器 @ December 21, 2009 |