作为DBA,在维护一个应用系统时,也许会遇到这样的问题,用户会抱怨在通过界面查询数据库中的数据时,显示出来的却是乱码,于是怀疑存储的数据成了乱码。特别是数据库中存放了简,繁2种字体的字符时,更容易出现这种问题,本文主要讨论数据库在存储简,繁体字符时出现的各种问题。
什么是数据库字符集(database characterset)?
数据库字符集通常可以理解为数据库提供的存储某种语言字符的一种环境.举个例子:英文,法文等文字每个字符占一个字节,而汉字一个字符需要2个字节,这就要求数据库提供相应的存储环境来存储这些字符.
字符集在数据库中的应用。
数据库在创建时是需要指定字符集的,它决定了以后数据库中所允许存放的语言字符,所以在系统设计当中,应当充分考虑数据库中可能存放的语言文字。在我们周围最常见的数据库字符集的问题就是存储,显示简体,繁体字符的问题.
和汉字相关的字符集
目前存放汉字的数据库最常用的两种字符集是ZHS16CGB231280和ZHS16GBK .前者只包含了大约7000多个汉字,很多生僻字和繁体字都没有包含进来.而ZHS16GBK是前者的一个扩展,大约包含了2.1万个汉字字符,基本上包括了所有的繁体字和生僻字.而这两种字符集又是大多数存储中文数据库中选用的字符集。
常见字符问题介绍
下面介绍的问题都是由于这着这两种字符集的兼容性产生的。
情况一 数据库字符集为ZHS16GBK,客户端字符集为:ZHS16GBK.
这种情况下数据库和客户端的字符集完全一致,在插入和显示简,繁体字 符时都不会有问题。
情况二数据库字符集为ZHS16GBK,客户端字符集为ZHS16CGB231280
由于客户端的字符集是数据库字符集的子集,,查询时有些繁体字会显示为乱码,原因是客户端的字符集中没有包含当前显示字符,其他的繁体字Oracle会根据客户端的字符集将他们穿换成简体字后显示出来。此时客户端能否插入繁体字成功取决于所插入的繁体字是否包含在数据库的字符集当中.
情况三数据库字符集为ZHS16CGB231280,客户端为ZHS16CGB231280.
可以显示繁体字.插入繁体字时如果插入的繁体字包含在数据库的字符集中就可以正常插入,否则报ORA-01756: 括号内的字符串没有正确结束,原因是Oracle由于自身字符集中没有包括该繁体字,所以将他作为单字节处理,导致语法解析时出错。
情况四数据库字符集为ZHS16CGB231280,客户端为ZHS16GBK.
此时客户端查询时,很多的繁体字显示为乱码,简体字可以正常显示.可以插入 繁体字,但繁体字插入后,Oracle会将它们全部转换成简体字.
结论
从以上几种情况可以看出:
出现乱码的原因是数据库,客户端的字符集不一致造成,只要修改客户端字符集就可以解决.客户端如果是linux系统,修改用户的环境变量中字符集的类型。如果是windows,直接修改注册表中Oracle_home下的NLS_LANG的值。
对于需要同时存储简体中文和繁体中文时,应首先选择ZHS16GBK,而不是ZHS16CGB231280,因为前者包含的字符是后者的3倍多.当然,现在的UNICODE字符集也可以选择,它可以存储各种语言字符.