遷移資料時oracle字符集的轉換遷移資料時oracle字符集的轉換

eric0435發表於2012-09-11
按照oracle官方文件所說,資料庫字符集在建立後原則上不能更改。因此,在設計和安裝之初考慮使用哪一種字符集十分重要。對資料庫server而言,錯誤的修改字符集將會導致很多不可測的後果,可能會嚴重影響資料庫的正常執行.但是由於每家軟體公司使用的字符集一樣,遷移資料時肯定是會遇到字符集轉換的問題.比如最常遇到是英文字符集轉換成中文,中文的轉換成英文.而且在遷移資料時都是上百GB的dmp檔案啊.
在遷移資料過程中我使用過兩種方法一是修改dmp檔案的字符集一是修改資料庫的字符集.
修改dmp檔案字符集,dmp檔案的第2第3位元組記錄了字符集資訊,因此直接修改dmp檔案的第2第3位元組的內容就可以‘騙’過oracle的檢查。這樣做理論上也僅是從子集到超集可以修改,但很多情況下在沒有子集和超集關係的情況下也可以修改,我們常用的一些字符集,如US7ASCII,WE8ISO8859P1,ZHS16CGB231280,ZHS16GBK基本都可以改。因為改的只是dmp檔案,所以影響不大。
具體的修改方法比較多,最簡單的就是直接用UltraEdit修改dmp檔案的第2和第3個位元組。
比如想將dmp檔案的字符集改為ZHS16GBK,可以用以下SQL查出該種字符集對應的16進位制程式碼: SQL> select to_char(nls_charset_id('ZHS16GBK'), 'xxxx') from dual;
0354 然後將dmp檔案的2、3位元組修改為0354即可,但是這樣種方法只能使用oracle8及以下版本的客戶端匯出的dmp才能修改
一種是修改資料庫字符集,因為官方文件是說建立資料庫後是不能修改,但是沒辦法工作需要在遷移資料時先建立一箇中間資料庫使用源資料庫的字符集進行建立的
將源資料庫的資料匯入中間資料庫後修改中間資料庫的字符集使其與目標資料庫的字符集一至,再從中間資料庫將資料匯入目標資料庫.我這樣做很麻煩,後面有一次由於
目標資料庫是沒有業務資料所以就直接修改了目標資料庫字符集將源資料庫的資料匯入進來了.
---1---修改資料庫裡的字符集
---中文字符集轉英文字符集
--英文
update sys.props$ set value$='US7ASCII' where name='NLS_CHARACTERSET';

commit;

update sys.props$ set value$='US7ASCII' where name='NLS_NCHAR_CHARACTERSET';
commit;

---2---修改強制同步資料庫裡的字符集
SHUTDOWN IMMEDIATE;

STARTUP MOUNT;

ALTER SYSTEM ENABLE RESTRICTED SESSION;

ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;

ALTER SYSTEM SET AQ_TM_PROCESSES=0;

ALTER DATABASE OPEN;

---給CHARSET變數賦值
COL VALUE NEW_VALUE CHARSET
SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_CHARACTERSET';

COL VALUE NEW_VALUE NCHARSET
SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_NCHAR_CHARACTERSET';

--INTERNAL_USE是沒有寫在文件中的引數,用以強制完成字符集一致化
ALTER DATABASE CHARACTER SET INTERNAL_USE &CHARSET;
--ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE &NCHARSET;

-- 再次啟動資料庫一遍
SHUTDOWN IMMEDIATE;
STARTUP;

set nls_lang=AMERICAN_AMERICA.US7ASCII;

---英文字符集轉中文字符集

update sys.props$ set value$='ZHS16GBK' where name='NLS_CHARACTERSET';

commit;

update sys.props$ set value$='ZHS16GBK' where name='NLS_NCHAR_CHARACTERSET';

commit;

---2---修改強制同步資料庫裡的字符集
SHUTDOWN IMMEDIATE;

STARTUP MOUNT;

ALTER SYSTEM ENABLE RESTRICTED SESSION;

ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;

ALTER SYSTEM SET AQ_TM_PROCESSES=0;

ALTER DATABASE OPEN;

---給CHARSET變數賦值
COL VALUE NEW_VALUE CHARSET
SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_CHARACTERSET';

COL VALUE NEW_VALUE NCHARSET
SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_NCHAR_CHARACTERSET';

--INTERNAL_USE是沒有寫在文件中的引數,用以強制完成字符集一致化
ALTER DATABASE CHARACTER SET INTERNAL_USE &CHARSET;
--ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE &NCHARSET;

-- 再次啟動資料庫一遍
SHUTDOWN IMMEDIATE;
STARTUP;


set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK;
1,修改dmp的時候,注意資料庫版本
9i以以下的資料庫,需要修改dmp檔案第1行的第2和第3個位元組
10g以上的資料庫,需要修改dmp檔案第3行的第3和第4個位元組


這個方法比較侷限,比如,你的資料庫10T,這個方法顯然就不行。。。。

2,強制修改是資料庫字符集
從10以後,oracle推薦使用csscan

3,補充一個,對於資料量大的資料庫整體遷移,這個方法顯然不行,僅僅是用於少量資料庫或者某些含多位元組(如中文)少的表
dblink+utl_raw

這是Lunar_Zhang給我的提供的另外的方法在這附上,謝謝他的方法 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26015009/viewspace-743098/,如需轉載,請註明出處,否則將追究法律責任。

相關文章