轉(zhuǎn)一位大神的筆記。
國內(nèi)最常用的Oracle字符集ZHS16GBK(GBK 16-bit Simplified Chinese)能夠支持繁體中文,并且按照2個字符長度存儲一個漢字驯杜。UTF8字符集是多字節(jié)存儲旨涝,1個漢字(簡體、繁體)有時采用3個字符長度存儲凛膏。
Oracle支持字符集的更改,但是UTF8是Oracle中最大的字符集,也就是說UTF8是ZHS16GBK的嚴格超集稠肘。
對于子集到超集的轉(zhuǎn)換,Oracle是允許的萝毛,但是對于超集到子集的轉(zhuǎn)換是不允許的项阴。一般對于超集到子集的轉(zhuǎn)換,建議是通過dbca刪除原來的數(shù)據(jù)庫笆包,重新再建庫环揽,選擇正確的字符集,然后導入備份庵佣。
我的方案是:先備份數(shù)據(jù)歉胶,然后強制轉(zhuǎn)換字符集從UTF8到ZHS16GBK,然后導入備份數(shù)據(jù)巴粪。如果不行通今,才來重新建庫粥谬,設(shè)置字符集ZHS16GBK,導入備份數(shù)據(jù)辫塌。如果這還不行漏策,就把更改字符集從ZHS16GBK到UTF8(這是安全的),再導入備份數(shù)據(jù)臼氨,恢復到原始狀況掺喻。這樣就有可能避開重新建庫的麻煩。
- 備份數(shù)據(jù)庫中所有用戶的數(shù)據(jù)
以oracle用戶登陸储矩,執(zhí)行以下命令
# export NLS_LANG = “SIMPLIFIED CHINESE_CHINA.UTF8”
保持與數(shù)據(jù)庫服務(wù)器端一致感耙,這樣在exp導出時,就不會存在字符的轉(zhuǎn)換了持隧,備份最原始的數(shù)據(jù)即硼。 - 評估UTF8轉(zhuǎn)換成ZHS16GBK的風險
轉(zhuǎn)換之前,要使用Oracle的csscan工具對數(shù)據(jù)庫掃描舆蝴,評估字符集轉(zhuǎn)換前后谦絮,數(shù)據(jù)有可能的損壞情況。如果評估情況糟糕洁仗,那就絕對要放棄了层皱。
先安裝屬于 CSMIG 用戶的一套表和過程。以oracle用戶登陸UNIX
≡省#sqlplus “/ as sysdab”
SQL>@$ORACLE_HOME/ rdbms/admin/csminst.sql
SQL>exit
# $ORACLE_HOME\bin\csscan -help
可以更清楚如何使用csscan叫胖。
# $ORACLE_HOME/bin/csscan system/sunday user=mmsc FROMCHAR=UTF8 TOCHAR=ZHS16GBK ARRAY=102400 PROCESS=3 > csscan.log
以上命令意思是掃描用戶:mmsc中的所有數(shù)據(jù),從字符集UTF8更改為ZHS16GBK的轉(zhuǎn)換情況她奥。然后得到三個文件:scan.txt瓮增、scan.out、scan.err哩俭。
查看scan.out绷跑,scan.err,可以看出mmsc用戶下的所有的數(shù)據(jù)都是可以轉(zhuǎn)換的凡资,并且沒有出現(xiàn)轉(zhuǎn)換“Exceptional”的情況砸捏,因此可以更放心一點。
- 更改數(shù)據(jù)庫的字符集為ZHS16GBK
前面說過隙赁,通過命令“Alter Database Characeter Set XXXX”垦藏,實現(xiàn)從超集到子集的轉(zhuǎn)換,在Oracle是不允許的伞访。但是該命令掂骏,提供這樣的命令方式:
Alter Database Character Set INTERNAL_CONVERT/ INTERNAL_USE XXXX
這是Oracle的非公開命令『裰溃“在使用這個命令時弟灼,Oracle會跳過所有子集及超集的檢查级解,在任意字符集之間進行強制轉(zhuǎn)換,所以袜爪,使用這個命令時你必須十分小心蠕趁,你必須清楚這一操作會帶來的風險”薛闪。
以oracle用戶登陸UNIX辛馆,
#sqlplus “/ as sysdba”
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
SQL> ALTER SESSION SET SQL_TRACE=TRUE;
SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0;
SQL> ALTER DATABASE OPEN;
SQL> ALTER DATABASE CHARACTER SET ZHS16GBK;
``
//如果不使用“INTERNAL_USE”參數(shù),系統(tǒng)會提示出錯:
//ERROR at line 1:
//ORA-12712: new character set must be a superset of old character set
SQL> ALTER SESSION SET SQL_TRACE=FALSE;
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP;
此時豁延,檢查一下數(shù)據(jù)庫的字符集是否更改過來
SQL> select value where name=’NLS_CHARACTERSET’;
VALUE$
-----------------
ZHS16GBK
緊接著檢查一下數(shù)據(jù)庫中簡體中文昙篙、繁體中文是否正常,不會出現(xiàn)亂碼诱咏。
SQL>select spid,spname,spshortname from spinfovisual_hk
…...
非常不幸苔可,我看到了一堆亂碼,這也證明了Oracle不支持字符集從超集到子集的更改袋狞,當時心里很緊張焚辅,很怕失敗,從而恢復到原樣苟鸯。
但是根據(jù)以前的驗證同蜻,把UTF8下的備份導入到ZHS16GBK中去,是OK的早处,所以繼續(xù)嘗試湾蔓。
4. 導入備份的用戶數(shù)據(jù)
還是以oracle用戶登陸UNIX, 先刪除庫中的用戶mmsc:
#sqlplus “/ as sysdba”
SQL>drop user mmsc cascade;
SQL>exit
再運行createuser.sql,生成mmsc用戶砌梆。
然后使用原來的備份文件默责,導入到mmsc用戶中:
注意:先設(shè)置NLS_LANG要與當前數(shù)據(jù)庫的一致:ZHS16GBK。這樣咸包,導出時用戶會話的NLS_LANG為UTF8桃序,與原先的數(shù)據(jù)庫字符集一致;現(xiàn)在為ZHS16GBK烂瘫,與此時的數(shù)據(jù)庫字符集一致媒熊。這樣,導入時忱反,就會進行字符轉(zhuǎn)換泛释。
# export NLS_LANG = “SIMPLIFIED CHINESE_CHINA.ZHS16GBK”
#imp mmsc/mmsc@mdspdb file=DSMPD113_user_mmsc.dmp ignore=y fromuser=mmsc touser=mmsc
馬上查看數(shù)據(jù)庫中簡體、繁體中文温算,沒有亂碼怜校,一切顯示正常。
緊接著進行驗證注竿,也證明了:1個漢字此時只占用2個字符長度茄茁。