Oracle汉字乱码问题原因及解决方法
[size=22pt]原因:出现中文乱码的主要原因是字符集不同。在Oracle中,我们关心三个地方的字符集:l Oracle服务器内部的字符集l NLS_LANG变量里保存的字符集l 客户端应用的字符集Oracle服务器内部的字符集这是Oracle数据库存储数据使用的字符集。在Oracle中可能使用Select userenv('language') from dual;或者:Select name, value$ from props$;查看。NLS_LANG变量里保存的字符集这个是Oracle设置的一个变量。在Windows中,这个变量保存在注册表中:HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/HOME0保存着NLS_LANG变量。在Unix/Linux中,则需要自己进行设置了。我本人是在.profile里面加上NLS_LANG=AMERICAN_AMERICA.ZHS16GBKexport NLS_LANG客户端应用的字符集使用Oracle里数据或者向Oracle提供数据的应用程序。如果 Oracle服务器内部的字符集 和 NLS_LANG变量里保存的字符集 相同,在进行Oracle查询时,就会将Oracle中的数据直接查出来,返回给查询用户。进行Oracle的插入操作,就会直接将插入的数据保存进数据库中。但是如果不同的话,Oracle查询时,会根据这两个字符集的一个映射,将数据库中的数据作一个转换,再返回给查询用户。进行插入操作时,也会根据映射,将插入的数据作一个转换,再插入数据库。这也是产生乱码的原因,这一层转换,把数据都给转乱了。[size=22pt]解决办法:将数据库的字符集和NLS_LANG字符集设置的一样,就可以避免乱码的出现了。修改数据库字符集的步骤如下:1、拥有修改权限(用管理用户登录)。SQL> conn sys/sys as sysdba;2、关闭数据库。SQL>shutdown immediate; 3、启动数据库到Mount状态下。SQL> STARTUP MOUNT;ORACLE instance started.Total System Global Area 76619308 bytesFixed Size 454188 bytesVariable Size 58720256 bytesDatabase Buffers 16777216 bytesRedo Buffers 667648 bytesDatabase mounted.SQL> ALTER SESSION SET SQL_TRACE=TRUE;Session altered.SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;System altered.SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;System altered.SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0;System altered.4、启动数据库SQL> Alter database open;5、修改字符集SQL> ALTER DATABASE CHARACTER SET ZHS16GBK;注:1. 如果数据库表中有CLOB类型的列,是不允许修改字符集的,解决方法为,先导出这个表的内容,然后删除这个表,修改完后,再导入这个表的内容就可以了。2. 旧的字符集必须是新的字符集的子集,否则不能修改。修改完后,可以查看一下修改是否成功。6、关闭数据库SQL> Shutdown immediate;7、重新启动数据库SQL> startup;经过设置完Oracle字符集后,一般的乱码问题应该解决掉了。在开发中,还遇到了这样一个问题:数据库服务器和应用服务器都布署在Solaris上面了,建库的脚本也是在Solaris上面执行的,在Solaris上面查询数据是正常的,但是在Windows上用浏览器看时,就会变成?了。这个问题的解决办法是,将数据库建库脚本在Windows上执行,再查看就都变正常了。 报错处理:1.若在此步发生下列报错处理:>alter database character set ZHS16GBK;ORA-12712: new character set must be a superset of old character set
RROR at line 1:结果报错,提示新字符集必须是老字符集的超集。于是强制转换>ALTER DATABASE character set INTERNAL_USE ZHS16GBK;>shutdown immediate;>STARTUP;问题解决。 不过这样很可能让你的数据库中原有的中文显示乱码,所以还请慎重。在改变字符集时最好新的字符集是老字符集的超集。 INTERNAL_USE是没有写在文档中的参数,用于强制完成字符集转化
alter database character set internal_use &charset;
alter database national character set internal_use &ncharset;