US7ASCII,實際存儲 GBK/GB2312 中文(常見於早期 Oracle 9i/10g)ZHS16GBKimp 會導致雙重轉碼產生亂碼# A 機環境變量
export NLS_LANG=AMERICAN_AMERICA.US7ASCII
# 正常 exp 導出,不做任何字符集轉換
exp userid=system/password file=full.dmp log=exp.log full=y
# B 機環境變量(關鍵:讓 imp 以認為數據是 US7ASCII)
export NLS_LANG=AMERICAN_AMERICA.US7ASCII
# 以 sysdba 修改目標庫字符集元數據(僅修改字典,不動數據文件)
sqlplus / as sysdba
UPDATE props$ SET value$ = 'US7ASCII' WHERE name = 'NLS_CHARACTERSET';
COMMIT;
SHUTDOWN IMMEDIATE;
STARTUP;
imp userid=system/password file=full.dmp log=imp.log full=y
# 此時 Oracle 讀取 dmp 視為 US7ASCII,寫入目標庫按 ZHS16GBK 存儲,完成正確轉碼
# 環境變量改回
export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
sqlplus / as sysdba
UPDATE props$ SET value$ = 'ZHS16GBK' WHERE name = 'NLS_CHARACTERSET';
COMMIT;
SHUTDOWN IMMEDIATE;
STARTUP;
# 查看中文是否正常
SELECT * FROM your_table WHERE chinese_col LIKE '%中文%';
# 不放心可再導出一次(現在庫是真 ZHS16GBK)
exp userid=system/password file=verify.dmp full=y
# 重建乾淨庫導入 verify.dmp,徹底消除元數據殘留風險
| 階段 | NLS_LANG | DB 字符集 | 實際操作 |
|---|---|---|---|
| 導出 | US7ASCII | US7ASCII | 二進位原樣讀出,無轉碼 |
| 導入 | US7ASCII | ZHS16GBK | Oracle 內部:US7ASCII(源) → Unicode → ZHS16GBK(目標) |
| 驗證 | ZHS16GBK | ZHS16GBK | 正常讀寫 |
UPDATE props$,或使用 ALTER DATABASE CHARACTER SET(需啟用 _system_trig_enabled)。ZHS16GBK 替換為 AL32UTF8,NLS_LANG 同步修改。CSALTER 腳本,易殘留系統表不一致。MySQL 同類場景(latin1 庫存 GBK)處理更簡單:mysqldump --default-character-set=latin1 導出 → 目標表建為 utf8mb4 → mysql --default-character-set=gbk 導入。Oracle 因字符集綁定在資料庫級別,需修改字典元數據「欺騙」匯入工具。