【背景介紹】
===================================================================
最近在使用Oracle9i數(shù)據(jù)庫進(jìn)行數(shù)據(jù)插入、查詢、導(dǎo)入/出,有時(shí)會出現(xiàn)亂碼的情況,具體的情形有以下兩種:
1.首次插入/顯示亂碼
2.首次插入/顯示正常、但把數(shù)據(jù)用工具導(dǎo)出為本地文件(例如TXT)文件,再在另一個(gè)客戶端中打開該文件并執(zhí)行時(shí)再次插入的數(shù)據(jù)顯示為亂碼。
遂在本地創(chuàng)建兩個(gè)數(shù)據(jù)庫,一個(gè)為AL32UTF8字符集,一個(gè)為ZHS16GBK字符集,配合客戶端NLS_LANG的不同設(shè)置,測試亂碼的情況及進(jìn)行原因分析。
===================================================================
【測試目的】
===================================================================
測試不同的數(shù)據(jù)庫字符集和客戶端NLS_LANG搭配下,中文字符/中文日期的插入、顯示
===================================================================
【測試環(huán)境】
===================================================================
Windows 2000 Professional (英文版) + Oracle 9.2.0.1.0 + SQL*Plus: Release 9.2.0.1.0
注:此次測試的客戶端應(yīng)用工具為SQL*PLUS,如果是使用TOAD、PL/SQL Develop之類工具,得到的結(jié)果會和以下有些不同。推薦使用SQL*PLUS作為一切客戶端應(yīng)用的測試工具
===================================================================
【測試數(shù)據(jù)庫】
===================================================================
本機(jī)數(shù)據(jù)庫1: SID: PAULLIN 登陸參數(shù): qprod/qprod@paullin
本機(jī)數(shù)據(jù)庫2:SID: PAUL 登陸參數(shù):qlinpen/pengpenglin@paul
===================================================================
【測試字符集】
===================================================================
客戶端應(yīng)用/操作系統(tǒng)字符集:GB2312
客戶端NLS_LANG設(shè)置:
AMERICAN_AMERICA.US7ASCII
AMERICAN_AMERICA.WE8MSWIN1252
AMERICAN_AMERICA.ZHS16GBK
AMERICAN_AMERICA.AL32UTF8
SIMPLIFIED CHINESE_CHINA.ZHS16GBK
數(shù)據(jù)庫端字符集:
PAULLIN: AL32UF8
PAUL: ZHS16GBK
===================================================================
【測試腳本】
===================================================================
--登陸數(shù)據(jù)庫
sqlplus qprod/qprod@paullin
sqlplus qlinpen/pengpenglin@paul
--執(zhí)行測試腳本
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,'易建聯(lián)');
commit;
insert into testdate values(TO_Date( '01/08/2008 04:14:00 下午',
'MM/DD/YYYY HH:MI:SS AM'));
commit;
--查看測試結(jié)果
select * from test;
select * from testdate;
===================================================================
【測試一:數(shù)據(jù)庫端字符集為AL32UTF8的情況】
===================================================================
1.登陸數(shù)據(jù)庫:
C:\Documents and Settings\qlinpen.E0015609D6309>sqlplus qprod/qprod@paullin
2.查看數(shù)據(jù)庫字符集:
SQL> select * from nls_database_parameters where parameter = 'NLS_CHARACTERSET';
3.測試內(nèi)容及測試結(jié)果:
1).客戶端NLS_LANG設(shè)置為AMERICAN_AMERICA.US7ASCII:
中文字符測試:插入/顯示中文字符均為亂碼
中文日期測試:ORA-01855: AM/A.M. or PM/P.M. required
2).客戶端NLS_LANG設(shè)置為AMERICAN_AMERICA.WE8MSWIN1252:
中文字符測試:插入/顯示中文字符均為正常
中文日期測試:ORA-01855: AM/A.M. or PM/P.M. required
3).客戶端NLS_LANG設(shè)置為AMERICAN_AMERICA.ZHS16GBK:
中文字符測試:插入/顯示中文字符均為正常
中文日期測試:ORA-01855: AM/A.M. or PM/P.M. required
4).客戶端NLS_LANG設(shè)置為AMERICAN_AMERICA.AL32UTF8:
中文字符測試:插入/顯示中文字符均為正常
中文日期測試:ORA-01855: AM/A.M. or PM/P.M. required
5).客戶端NLS_LANG設(shè)置為SIMPLIFIED CHINESE_CHINA.ZHS16GBK:
中文字符測試:插入/顯示中文均為正常
中文日期測試:插入/顯示中文日期均為正常,格式為DD-MM-YY(例如:08-1月 -08)
4.測試結(jié)論:
從測試結(jié)果來看,當(dāng)數(shù)據(jù)庫端字符集為AL32UTF8時(shí),能夠使到中文字符被正確插入/顯示的NLS_LANG的字符集為: WE8MSWIN1252、ZHS16GBK、AL32UTF8。
但是要使到中文格式的時(shí)間能夠被正確插入,則NLS_LANG的LANGUAGE和TERRITORY設(shè)置必須為:SIMPLIFIED_CHINESE_CHINA
===================================================================
【測試二:數(shù)據(jù)庫端字符集為ZHS16GBK的情況】
===================================================================
1.登陸數(shù)據(jù)庫:
C:\Documents and Settings\qlinpen.E0015609D6309>sqlplus qlinpen/pengpenglin@paul
2.查看數(shù)據(jù)庫字符集:
SQL> select * from nls_database_parameters where parameter = 'NLS_CHARACTERSET';
3.測試內(nèi)容及測試結(jié)果:
1).客戶端NLS_LANG設(shè)置為AMERICAN_AMERICA.US7ASCII:
中文字符測試:插入/顯示中文字符均為亂碼
中文日期測試:ORA-01855: AM/A.M. or PM/P.M. required
2).客戶端NLS_LANG設(shè)置為AMERICAN_AMERICA.WE8MSWIN1252:
中文字符測試:插入/顯示中文字符均為亂碼
中文日期測試:ORA-01855: AM/A.M. or PM/P.M. required
3).客戶端NLS_LANG設(shè)置為AMERICAN_AMERICA.ZHS16GBK:
中文字符測試:插入/顯示中文字符均為正常
中文日期測試:ORA-01855: AM/A.M. or PM/P.M. required
4).客戶端NLS_LANG設(shè)置為AMERICAN_AMERICA.AL32UTF8:
中文字符測試:插入/顯示中文字符均為亂碼
中文日期測試:ORA-01855: AM/A.M. or PM/P.M. required
5).客戶端NLS_LANG設(shè)置為SIMPLIFIED CHINESE_CHINA.ZHS16GBK:
中文字符測試:插入/顯示中文均為正常
中文日期測試:插入/顯示中文日期均為正常,格式為DD-MM-YY(例如:08-1月 -08)
4.測試結(jié)論:
從測試結(jié)果來看,當(dāng)數(shù)據(jù)庫端字符集為ZHS16GBK時(shí),能夠使到中文字符被正常插入/顯示的NLS_LANG的字符集為:ZHS16GBK。
而且要使到中文格式的時(shí)間能夠被正確插入,則NLS_LANG的LANGUAGE和TERRITORY設(shè)置必須為:SIMPLIFIED CHINESE_CHINA
===================================================================
【測試總結(jié)】
===================================================================
從上面兩個(gè)測試的結(jié)果就可以明顯看出,把數(shù)據(jù)庫端的字符集設(shè)置為AL32UTF8比起ZHS16GBK更加有優(yōu)勢。
UTF8支持從客戶端應(yīng)用字符集為WE8MSWIN1252、ZHS16GBK、AL32UTF8的環(huán)境下進(jìn)行中文字符的插入,而ZHS16GBK只支持客戶端應(yīng)用字符集為ZHS16GBK環(huán)境下的的中文字符插入。
其次我們來看看日期格式為:01/08/2008 04:14:00 下午的記錄為什么只能在NLS_LANG的LANGUAGE和TERRITORY為SIMPLIFIED CHINESE_CHINA的情況下才能正確插入?
我們知道客戶端NLS_LANG的值由3部分構(gòu)成,即<LANUAGE>_<TERRITORY>.<CHARACTERSET>,而掌管日期中月份和日顯示的恰恰就是<LANGUAGE>部分,所以很明顯<LANGUAGE>為AMERICAN的情況下,是不可能正確插入的(西方用AM、PM來表示上、下午)。
依次類推,如果以后出現(xiàn)貨幣和數(shù)字格式、地區(qū)和計(jì)算星期及日期的習(xí)慣插入、轉(zhuǎn)換失敗,那么我們就要檢查第二個(gè)元素<TERRITORY>。
===================================================================
-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
posted on 2008-04-23 14:59
Paul Lin 閱讀(7845)
評論(0) 編輯 收藏 所屬分類:
Oracle 管理