EXP遇到ORA-06552錯誤的解決( PLS-553: character set name is not recognized)2009-05-08 16:51有一個建好的資料,Oracle 9.2.0.4 for linux,字元集是預設的WE8ISO8859P1,沒有改成ZHS16GBK. 庫中暫時沒有任何資料。
由於字元集不是超集/子集關係,無法通過ALTER DATABASE CHARACTER SET修改字元集。
當時時間緊張,就沒有重建資料庫,而是直接修改prop$表,將NLS_CHAR字元集改為ZHS16GBK。
update props$ set value$='ZHS16GBK' where name='NLS_CHARACTERSET';
重啟後建表、insert資料,一切正常。。。直到今天要exp出資料。
執行 exp userid=system owner=username ... 報錯!
即將匯出指定的使用者…
. 正在匯出 pre-schema 過程對象和操作
. 正在匯出使用者 USERNAME 的外部函數庫名稱
. 匯出 PUBLIC 類型同義字
EXP-00008: 遇到 ORACLE 錯誤 6552
ORA-06552: PL/SQL: Compilation unit analysis terminated
ORA-06553: PLS-553: character set name is not recognized
EXP-00000: 匯出終止失敗
隱隱感覺與當時的字元集設定有關。http://www.eygle.com/special/NLS_CHARACTER_SET_03.htm: “正式修改字元集時,Oracle至少需要更改12張資料字典表,而這種直接更新props$表的方式只完成了其中十二分之一的工作,潛在的完整性隱患是可想而知的。”
但是如何解決呢?後來搜尋到未公開的INTERNAL_USE用法,強制完成字元集一致化,解決了問題。
首先,確認字元集是否修改的不徹底。
SELECT DISTINCT (NLS_CHARSET_NAME(CHARSETID)) CHARACTERSET,
DECODE(TYPE#, 1,
DECODE(CHARSETFORM, 1, 'VARCHAR2', 2, 'NVARCHAR2', 'UNKOWN'),
9,
DECODE(CHARSETFORM, 1, 'VARCHAR', 2, 'NCHAR VARYING', 'UNKOWN'),
96,
DECODE(CHARSETFORM, 1, 'CHAR', 2, 'NCHAR', 'UNKOWN'),
112,
DECODE(CHARSETFORM, 1, 'CLOB', 2, 'NCLOB', 'UNKOWN')) TYPES_USED_IN
FROM SYS.COL$
WHERE CHARSETFORM IN (1, 2)
AND TYPE# IN (1, 9, 96, 112);
如果上面的查詢的確顯示有多個字元集的設定,則進行如下處理:
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;
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;
-- 再次啟動資料庫一遍
SHUTDOWN IMMEDIATE;
STARTUP;
至此,EXP問題得到瞭解決。
注意:修改字元集只是修改了資料字典,並沒有對資料進行字元集轉換!
轉