关于Oracle数据库字符集的选择(4)

我们前面讲过,SQL*PLUS工具不提供编码自动转换的功能,当数据库字符集为UTF8,客户端的NLS_LANG如果也是UTF8,那么在SQL*PLUS中运行SQL语句时,语句全是英文,不会出现问题,如果语句包含了中文或其它一些特殊字符,SQL语句运行时就会报错。对于返回的含中文的结果,SQL*PLUS也会显示乱码。

造成此错误的原因在于当SQL语句中包含汉字等一些特殊字符时,由于这些字符的编码属于GBK,ORACLE没有进行字符转换,而是直接把SQL语句送到服务器上进行解析。此时服务器的字符集是UTF8,因此它按UTF8编码格式对SQL语句中GBK编码的字符解析时就会产生错误。如果把客户端的NLS_LANG设置为本地环境的字符集,如ZHS16GBK,此时可以直接在SQL*PLUS中输入包含中文的SQL语句,ORACLE在把SQL语句提交到服务器时会自动转换成UTF8编码格式,因此SQL语句可以正常运行。对于英文字母,由于它在UTF8中的编码数值采用的还是ASCII的编码数值,因此英文字母可以直接使用而不需要转换,这就是如果SQL语句或输出结果全是英文时不会出现错误的原因。

正确的做法是先把需要运行的SQL做成脚本文件,用代码转换工具把它转换成UTF8编码格式的文件,(注意!XP中的记事本是提供了代码转换功能的,可以在保存文件或选择文件另存为的时候,弹出的对话框最后一项,编码,选择UTF8,再保存,即可把文件转换成UTF8编码格式)。完成后用IE打开这个脚本,选择编码-》UTF8,观察此时SQL脚本是否含有乱码或“?”符号。如果没有,说明编码格式已经是UTF8了,此时在SQL*PLUS中运行这个脚本就不会产生错误了。运行结束后,输出的结果中如果包含中文,需要把结果SPOOL输出到一个文件中,然后用代码转换工具把这个结果文件由UTF8转换成本地编码格式,再用写字板打开,才能看到正常显示的汉字。由于IE具有代码转换功能,因此也可以不用代码转换工具,直接在IE中打开输出的结果文件,选择UTF8编码,也能正常显示含中文的结果文件。

4.2、数据库出现乱码的问题:

数据库出现乱码的问题主要和客户的本地化环境,客户端NLS_LANG设置,服务器端的数据库字符集设置这三者有关,如果它们的设置不一致或者某个设置错误,就会很容易出现乱码,下面我们简要介绍以下几种情况:

4.2.1、数据库字符集设置不当引起的乱码:

这种错误是由于数据库字符集选择错误而引起的。我们前面讲过,由于每种语言文字都有一些自己特殊的字符,甚至一些字符的写法都有不同的讲究,因此即使对于欧美国家来说,也不是可以随便通用的。像西欧的字符集标准ISO 8859-1是8位编码,它就有自己的一些特殊符号,这些字符在US7ASCII编码中找不到对应的编码值。如果需要使用这些特殊符号,就必须选用本地字符集或者是它的超集的字符集。如果选用的字符集两者都不是,那么在数据库存储的数据实际编码和数据库字符集的设置就产生了不一致,很容易产生乱码。

例如:一个存储简体中文字符的数据库,它的字符集选用了US7ASCII,当它的客户端NLS_LANG也选用US7ASCII时,这个系统单独使用是没有问题的,因为两者设置一致,因此ORACLE不会进行字符集的转换,客户输入的GBK码被直接在数据库中存储起来,当查询数据时,实际客户端取出来的数据也是GBK的编码,因此显示也是正常的。但当其它的系统需要从这个数据库取数据,或者它的数据要EXP出来,IMP到其它数据库时,问题就会开始出现了。其它系统的字符集一般是ZHS16GBK,或者其它系统客户端的NLS_LANG设置为ZHS16GBK,此时必然会产生字符集的转换。虽然数据库字符集设置为US7ASCII,但我们知道,实际存储的数据编码是ZHS16GBK的。可惜ORACLE不会知道,它会把存储的ZHS16GBK编码数据当作US7ASCII编码的数据,按照US7ASCII转换成ZHS16GBK的转换算法进行转换,可以想象,这种情况下,乱码的产生是必然的。

结论是:如果要选择一个非本地环境的数据库字符集,在不需要考虑和其它系统的数据接口和数据交换的情况下,或者你有面对这种麻烦的心理准备的话,那么这种选择是可行的,但是别忘了数据库字符集一定要和客户端的NLS_LANG保持一致。

4.2.2、数据库字符集与客户端NLS_LANG设置不同引起的乱码:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/cc1e70b3486a8bdb723522ff48089a17.html