引言
ORACLE数据库作为业界领先的数据库产品近年来在国内大中型企业中得到了广泛的应用虽然ORACLE数据库产品本身在本地化方面已做得相当成熟但还是有不少用户反应汉字显示乱码的问题如对同一数据库不同的用户对同一表中的username查询却得出了不同的结果
“ORACLE??????”和“ORACLE中国有限公司”显然结果中将中文字符显示为乱码那么为什么呢?字符集的设置不当是影响ORACLE数据库汉字显示的关键问题
关于字符集
字符集是ORACLE为适应不同语言文字显示而设定的用于汉字显示的字符集主要有ZHSCGBZHSGBKUSASCII和UTF等字符集同时存在于服务器端和客户端服务器端字符集是在安装ORACLE时指定的字符集登记信息存储在ORACLE数据库字典的V$NLS_PARAMETERS表中;而客户端字符集是在系统注册表(WINDOWS系统)或在用户的环境变量(UNIX系统)中设定的
字符集的构成与设定
字符集的构成与设定方式分为客户端与服务器端两种
()客户端字符集的构成与设定客户端的字符集是由当前用户的环境变量NLS_LANG设定的环境变量NLS_LANG的构成
NLS_LANG=language_territorycharset
其中
language 指定服务器消息的语言
territory 指定服务器的日期和数字格式
charset 指定字符集
三个成分可以任意组合例如
AMERICAN_AMERICAUSSCII
SIMPLIFIED CHINESE_CHINAZHSGBK
AMERICAN_AMERICA ZHSGBK
客户端字符集的设定方法针对不同操作系统设定方法稍有不同WINDOWS系统是在注册表项HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOME\NLS_LANG中设定;UNIX系统是在当前用户的环境变量中设定如在当前用户的profile文件中增加一行如下代码
NLS_LANG=SIMPLIFIED Chinese_CHINAZHSGBK;export NLS_LANG
()服务端字符集的构成与设定服务端字符集的构成体现在数据字典表V$NLS_PARAMETERS的NLS_LANGUAGENLS_TERRITORYNLS_CHARACTERSET三项取值上其中NLS_CHARACTERSET的取值就是具体的数据库字符集
如利用查询语句SQL>SELECT * FROM V$NLS_PARAMETERS;
可得到如下结果
PARAMETER VALUE
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
……
NLS_CHARACTERSET ZHSGBK
……
即当前数据库使用的字符集是ZHSGBK
数据库服务端的字符集是在创建数据时设定的但可通过如下方法对已设定的字符集进行修改
方法一重建数据库建立数据库时将数据库的字符集设定为所需字符集
方法二修改SYSPROPS$表即用SYS用户登陆ORACLE后利用下面语句修改相应的字符集并提交
SQL>UPDATE PROPS$ SET VALUE$=’ZHSGBK‘
WHERE NAME=’NLS_CHARACTERSET’;
SQL>COMMIT;
通过此种方法来更改数据库字符集只对更改后的数据有效即数据库中原来的数据仍以原字符集被存储
另外有的还利用CREATE DATABASE CHARACTER SET ZHSGBK命令暂时的修改字符集当重启数据库后数据库字符集将恢复原来的字符集
常见的汉字乱码问题及解决方案
要在客户端正确显示ORACLE数据库中的汉字信息首先必须使客户端的字符集与服务器端的字符集一致;其次是加载到ORACLE数据库的数据字符集必须与服务器字符集一致据此汉字显示乱码的问题大致可以分为以下几种情况
()客户端字符集与服务器端字符集不同服务器端字符集与加载数据字符集一致这种情况是最常见的只要把客户端的字符集设置正确即可具体解决方案
第一步查询V$NLS_PARAMETERS得到服务端的字符集
SQL>SELECT * FROM V$NLS_PARAMETERS;
第二步根据服务端的字符集设定客户端的字符集设定方法参见客户端的字符集的设定方式
以UNIX系统为例可在当前用户的profile文件中增加如下两行
NLS_LANG=SIMPLIFIED Chinese_CHINAZHSGBK
export NLS_LANG
()客户端字符集与服务器端字符集相同服务器端字符集与加载数据字符集不一致这种情况一般发生在ORACLE版本升级或重新安装数据库时选择了与原来数据库不同的字符集而恢复加载的备份数据仍是按原字符集卸出的场合另一种情况是加载从其它使用不同字符集的ORACLE数据库卸出的数据在这两种情况中不管客户端字符集与服务器端字符集是否一致都无法正确显示汉字具体解决方案
方案一按服务端字符集的修改方法修改服务端字符集与加载数据字符集一致然后导入数据
方案二利用数据格式转储避开字符集带来的问题即先将加载数据倒入到与其字符集一致的数据库中然后再将数据要么按文本格式导出(数据量较小的情况下)要么通过第三方工具(如POWER BUILDERACCESSFOXPRO等)倒出数据最后将倒出的数据导入到目标数据库中
()客户端字符集与服务器端字符集不同服务端字符集与输入数据字符集不同这种情况是在客户端字符集与服务器端字符集不一致时从客户端输入了汉字信息输入的这些信息即便是把客户端字符集更改正确也无法显示汉字解决方案修改客户端字符集与服务端字符集一致后重新输入数据
其中:
sqlplus乱码解决
export NLS_LANG=AMERICAN_AMERICAZHSGBK (显示英文)
或
export NLS_LANG="SIMPLIFIED CHINESE"_CHINAzhscgb
(显示简体中文)
结束语
根据ORACLE官方文档的说明一旦数据库创建后数据库的字符集是不能改变的因此提前考虑自己的数据库将选用哪一种字符集是十分重要的数据库字符集选择的一般规则是将数据库字符集设定为操作系统本地字符集的一个超集同时数据库字符集也应该是所有客户字符集的超集如同样是中文环境在选择ZHSCGB还是ZHSGBK时我们更多的情况是选择ZHSGBK因为它包含了ZHSCGB字符集