【原创】Oracle管理专题之:Oracle9i 字符集与NLS_LANG搭配测试兼乱码问题分析
【背景介绍】
===================================================================
最近在使用Oracle9i数据库进行数据插入、查询、导入/出,有时会出现乱码的状况,具体的情形有如下两种:
1.首次插入/显示乱码
2.首次插入/显示正常、但把数据用工具导出为本地文件(例如TXT)文件,再在另外一个客户端中打开该文件并执行时再次插入的数据显示为乱码。
遂在本地建立两个数据库,一个为AL32UTF8字符集,一个为ZHS16GBK字符集,配合客户端NLS_LANG的不一样设置,测试乱码的状况及进行缘由分析。
===================================================================
【测试目的】
===================================================================
测试不一样的数据库字符集和客户端NLS_LANG搭配下,中文字符/中文日期的插入、显示
===================================================================
【测试环境】
===================================================================
Windows 2000 Professional (英文版) + Oracle 9.2.0.1.0 + SQL*Plus: Release 9.2.0.1.0
注:这次测试的客户端应用工具为SQL*PLUS,若是是使用TOAD、PL/SQL Develop之类工具,获得的结果会和如下有些不一样。推荐使用SQL*PLUS做为一切客户端应用的测试工具
===================================================================
【测试数据库】
===================================================================
本机数据库1: SID: PAULLIN 登录参数: qprod/qprod@paullin
本机数据库2:SID: PAUL 登录参数:qlinpen/pengpenglin@paul
===================================================================
【测试字符集】
===================================================================
客户端应用/操做系统字符集:GB2312
客户端NLS_LANG设置:
AMERICAN_AMERICA.US7ASCII
AMERICAN_AMERICA.WE8MSWIN1252
AMERICAN_AMERICA.ZHS16GBK
AMERICAN_AMERICA.AL32UTF8
SIMPLIFIED CHINESE_CHINA.ZHS16GBK
数据库端字符集:
PAULLIN: AL32UF8
PAUL: ZHS16GBK
===================================================================
【测试脚本】
===================================================================
--登录数据库
sqlplus qprod/qprod@paullin
sqlplus qlinpen/pengpenglin@paul
--执行测试脚本
drop table test;
drop table testdate;
create table test (id number(1), name varchar2(20));
create table testdate (birthday date);
insert into test values(1,'Tom');
insert into test values(2,'张三');
insert into test values(3,'易建聯');
commit;
insert into testdate values(TO_Date( '01/08/2008 04:14:00 下午',
'MM/DD/YYYY HH:MI:SS AM'));
commit;
--查看测试结果
select * from test;
select * from testdate;
===================================================================
【测试一:数据库端字符集为AL32UTF8的状况】
===================================================================
1.登录数据库:
C:\Documents and Settings\qlinpen.E0015609D6309>sqlplus qprod/qprod@paullin
2.查看数据库字符集:
SQL> select * from nls_database_parameters where parameter = 'NLS_CHARACTERSET';
3.测试内容及测试结果:
1).客户端NLS_LANG设置为AMERICAN_AMERICA.US7ASCII:
中文字符测试:插入/显示中文字符均为乱码
中文日期测试:ORA-01855: AM/A.M. or PM/P.M. required
2).客户端NLS_LANG设置为AMERICAN_AMERICA.WE8MSWIN1252:
中文字符测试:插入/显示中文字符均为正常
中文日期测试:ORA-01855: AM/A.M. or PM/P.M. required
3).客户端NLS_LANG设置为AMERICAN_AMERICA.ZHS16GBK:
中文字符测试:插入/显示中文字符均为正常
中文日期测试:ORA-01855: AM/A.M. or PM/P.M. required
4).客户端NLS_LANG设置为AMERICAN_AMERICA.AL32UTF8:
中文字符测试:插入/显示中文字符均为正常
中文日期测试:ORA-01855: AM/A.M. or PM/P.M. required
5).客户端NLS_LANG设置为SIMPLIFIED CHINESE_CHINA.ZHS16GBK:
中文字符测试:插入/显示中文均为正常
中文日期测试:插入/显示中文日期均为正常,格式为DD-MM-YY(例如:08-1月 -08)
4.测试结论:
从测试结果来看,当数据库端字符集为AL32UTF8时,可以使到中文字符被正确插入/显示的NLS_LANG的字符集为: WE8MSWIN125二、ZHS16GBK、AL32UTF8。
可是要使到中文格式的时间可以被正确插入,则NLS_LANG的LANGUAGE和TERRITORY设置必须为:SIMPLIFIED_CHINESE_CHINA
===================================================================
【测试二:数据库端字符集为ZHS16GBK的状况】
===================================================================
1.登录数据库:
C:\Documents and Settings\qlinpen.E0015609D6309>sqlplus qlinpen/pengpenglin@paul
2.查看数据库字符集:
SQL> select * from nls_database_parameters where parameter = 'NLS_CHARACTERSET';
3.测试内容及测试结果:
1).客户端NLS_LANG设置为AMERICAN_AMERICA.US7ASCII:
中文字符测试:插入/显示中文字符均为乱码
中文日期测试:ORA-01855: AM/A.M. or PM/P.M. required
2).客户端NLS_LANG设置为AMERICAN_AMERICA.WE8MSWIN1252:
中文字符测试:插入/显示中文字符均为乱码
中文日期测试:ORA-01855: AM/A.M. or PM/P.M. required
3).客户端NLS_LANG设置为AMERICAN_AMERICA.ZHS16GBK:
中文字符测试:插入/显示中文字符均为正常
中文日期测试:ORA-01855: AM/A.M. or PM/P.M. required
4).客户端NLS_LANG设置为AMERICAN_AMERICA.AL32UTF8:
中文字符测试:插入/显示中文字符均为乱码
中文日期测试:ORA-01855: AM/A.M. or PM/P.M. required
5).客户端NLS_LANG设置为SIMPLIFIED CHINESE_CHINA.ZHS16GBK:
中文字符测试:插入/显示中文均为正常
中文日期测试:插入/显示中文日期均为正常,格式为DD-MM-YY(例如:08-1月 -08)
4.测试结论:
从测试结果来看,当数据库端字符集为ZHS16GBK时,可以使到中文字符被正常插入/显示的NLS_LANG的字符集为:ZHS16GBK。
并且要使到中文格式的时间可以被正确插入,则NLS_LANG的LANGUAGE和TERRITORY设置必须为:SIMPLIFIED CHINESE_CHINA
===================================================================
【测试总结】=================================================================== 从上面两个测试的结果就能够明显看出,把数据库端的字符集设置为AL32UTF8比起ZHS16GBK更加有优点。UTF8支持从客户端应用字符集为WE8MSWIN125二、ZHS16GBK、AL32UTF8的环境下进行中文字符的插入,而ZHS16GBK只支持客户端应用字符集为ZHS16GBK环境下的的中文字符插入。其次咱们来看看日期格式为:01/08/2008 04:14:00 下午的记录为何只能在NLS_LANG的LANGUAGE和TERRITORY为SIMPLIFIED CHINESE_CHINA的状况下才能正确插入?咱们知道客户端NLS_LANG的值由3部分构成,即<LANUAGE>_<TERRITORY>.<CHARACTERSET>,而掌管日期中月份和日显示的偏偏就是<LANGUAGE>部分,因此很明显<LANGUAGE>为AMERICAN的状况下,是不可能正确插入的(西方用AM、PM来表示上、下午)。依次类推,若是之后出现货币和数字格式、地区和计算星期及日期的习惯插入、转换失败,那么咱们就要检查第二个元素<TERRITORY>。
欢迎关注本站公众号,获取更多信息