同事在中文 Windows 上安裝 Oracle 10g,後因業務需求將 OS 改為日文環境,導致資料庫內部出現亂碼。根因:安裝時 Oracle 依據 OS 語言自動選擇字元集(中文環境預設 ZHS16GBK),OS 改日文後,字元集解讀錯誤。本文提供三種修復路徑,依資料量與停機容忍度選擇。
NLS_LANG):HKEY_LOCAL_MACHINE\SOFTWARE\OracleHKEY_LOCAL_MACHINE\SOFTWARE\Oracle\HOME0(或對應 HOME)NLS_LANG 改為 JAPANESE_JAPAN.JA16SJIS(或 JA16SJISTILDE)。net stop OracleServiceORCL & net start OracleServiceORCL。JA16SJIS,國字集 AL16UTF16。impdp / sqlldr)。前提:資料庫無業務資料,或資料可接受重新載入。
NLS_LANG 並重啟服務。SYS 連線(需 SYSDBA),更新字元集屬性:-- 查看目前字元集
SELECT * FROM sys.props$ WHERE name IN ('NLS_CHARACTERSET','NLS_NCHAR_CHARACTERSET');
-- 更新為日文字元集
UPDATE sys.props$ SET value$ = 'JA16SJIS' WHERE name = 'NLS_CHARACTERSET';
UPDATE sys.props$ SET value$ = 'JA16SJIS' WHERE name = 'NLS_NCHAR_CHARACTERSET';
COMMIT;
-- 重啟資料庫生效
SHUTDOWN IMMEDIATE;
STARTUP;
風險:直接更新 SYS.PROPS$ 為非官方支援操作,若資料庫已有資料,字元集轉換會導致資料損毀。僅限空庫或測試環境使用。
expdp FULL=Y)。JA16SJIS)的新資料庫。CSALTER 腳本(需 Oracle 支援協助)或 DMU (Database Migration Assistant for Unicode) 進行字元集轉換。查詢合法字元集 ID 與名稱:
SELECT nls_charset_id(value) AS charset_id, value AS charset_name
FROM v$nls_valid_values
WHERE parameter = 'CHARACTERSET'
ORDER BY charset_id;
NLS_LANG 格式:LANGUAGE_TERRITORY.CHARACTERSET,三段缺一不可。NLS_LANG 需與資料庫字元集相容,否則仍會出現轉換錯誤或資料截斷。字元集亂碼本質是「編碼宣告與實際位元組不符」。依資料重要性選擇「重建最乾淨、遷移最安全、直接改庫最快但最危險」,切勿在有資料的生產庫直接 UPDATE SYS.PROPS$ 僥倖過關。