【背景介紹】
===================================================================
最近在使用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的字符集為: WE8MSWIN1252、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支持從客戶端應用字符集為WE8MSWIN1252、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>。
===================================================================
-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
posted on 2008-04-23 14:59
Paul Lin 閱讀(7845)
評論(0) 編輯 收藏 所屬分類:
Oracle 管理