Oracle 亂碼源於 **資料庫字元集**、**客戶端字元集 (NLS_LANG)**、**作業系統字元集** 三者不一致導致的轉換錯誤。掌握轉換流向即能精準定位與修復。
輸入端:應用輸入(OS字元集) → 客戶端(NLS_LANG) → 資料庫(DB字元集) → 儲存
輸出端:資料庫(DB字元集) → 客戶端(NLS_LANG) → 顯示(OS字元集) → 螢幕
| 階段 | DB字元集 | 客戶端NLS_LANG | OS字元集 | 輸入/查詢結果 |
|---|---|---|---|---|
| 初始 | ZHS16GBK | ZHS16GBK | CP936(GBK) | ✅ 正常顯示「漢字輸入測試」 |
| 改客戶端為UTF8 | ZHS16GBK | UTF8 | CP936 | ❌ 亂碼:存入時 GBK→UTF8→GBK 雙重錯誤轉換 |
| UTF8客戶端再插入 | ZHS16GBK | UTF8 | CP936 | ❌ 新資料亂碼不同(輸入被誤判為UTF8再轉GBK) |
| 改回GBK客戶端 | ZHS16GBK | ZHS16GBK | CP936 | ✅ 舊資料恢復,❌ 新資料仍亂(已寫錯磁碟) |
| 場景 | 解法 | 操作 |
|---|---|---|
| Windows 客戶端 | 修改註冊表 | HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_... \NLS_LANG = SIMPLIFIED CHINESE_CHINA.ZHS16GBK |
| Linux/Unix 客戶端 | 環境變數 | export NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK (寫入 .bash_profile) |
| JDBC/ODBC 應用 | 連線屬性 | JDBC 不依賴 NLS_LANG,確認 oracle.jdbc.defaultNChar=true 或驅動程式設定 |
| 資料庫字元集需變更 | 重建資料庫 | 字元集建庫後不可變,需匯出/建庫/匯入 |
-- 查資料庫字元集
SELECT * FROM DATABASE_PROPERTIES WHERE PROPERTY_NAME='NLS_CHARACTERSET';
-- 查目前會話參數
SELECT * FROM NLS_SESSION_PARAMETERS WHERE PARAMETER LIKE '%CHARACTERSET%';
避坑精髓:安裝 Oracle Client 時**務必**將 NLS_LANG 設為與 OS 終端機編碼一致(中文環境多為 ZHS16GBK/AL32UTF8),而非資料庫字元集。資料庫字元集建議統一
AL32UTF8,客戶端跟隨 OS。