Oracle 字元集定義位元組資料的解讀方式,具備大小與包含關係 (子集 → 超集)。關鍵參數 NLS_LANG = LANGUAGE_TERRITORY.CHARSET 三部分分別控制訊息語言、日期/數字格式、字元集。**真正影響資料儲存與交換的是第三部分 CHARSET**。
| 層級 | 查詢方式 | 範例結果 |
|---|---|---|
| 資料庫伺服器端 | SELECT USERENV('LANGUAGE') FROM DUAL; | AMERICAN_AMERICA.ZHS16GBK |
| 用戶端環境 | Windows: 登錄表 HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOMEUnix: echo $NLS_LANG | AMERICAN_AMERICA.ZHS16GBK |
| DMP 匯出檔 | 小檔: UltraEdit 開啟十六進位看第 2-3 位元組 → SELECT NLS_CHARSET_NAME(TO_NUMBER('xxxx','XXXX')) FROM DUAL;大檔: cat exp.dmp | od -x | head -1 | awk '{print $2$3}' | cut -c3-6 同前查詢 | 第 2-3 位元組 0354 → ZHS16GBK |
US7ASCII ⊂ ZHS16GBK、UTF8 (最大,Unicode 基礎)ZHS16GBK 與 ZHS16CGB231280 **無包含關係,理論不支援互轉**SQLPLUS /NOLOG
CONN / AS SYSDBA
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;
ALTER DATABASE CHARACTER SET ZHS16GBK; -- 目標字元集
ALTER DATABASE NATIONAL CHARACTER SET ZHS16GBK;
SHUTDOWN IMMEDIATE
STARTUP
風險:Oracle 8+ 至少三張系統表記錄字元集,僅改 PROPS$ 不完整,可能導致資料字典損壞、啟動失敗。
SELECT TO_CHAR(NLS_CHARSET_ID('ZHS16GBK'),'XXXX') FROM DUAL; → 0354EXP/IMP 或 DATAPUMP,Oracle 自動轉碼-- 方案 A: 以 UTF8 為中介 (通用超集)
-- 來源 (ZHS16GBK) → UTF8 中介庫 → 目標 (ZHS16CGB231280)
-- 方案 B: 程式碼層面轉碼 (Java/Python cx_Oracle) 逐筆讀寫
-- 方案 C: 建立目標字元集新庫,用 DB Link 或外部表搭配 CONVERT() 函數轉碼
| 現象 | 原因 | 對策 |
|---|---|---|
| 中文變 ??? 或 | 用戶端 NLS_LANG 與資料庫不符 | 統一設定為資料庫字元集 (如 ZHS16GBK) |
| 匯入後中文變亂碼 | DMP 字元集標記錯誤或匯入時字元集不匹配 | 修正 DMP 標記或用 UTF8 中介庫 |
| DB Link 查詢遠端中文亂碼 | 兩端字元集不同且無隱含轉換 | 遠端建立 UTF8 View 用 CONVERT(),本地查 View |
| JDBC 讀取中文亂碼 | JDBC Thin Driver 預設用 UTF-8,資料庫非 UTF8 | 確認 oracle.jdbc.defaultNChar 或升級驅動/資料庫至 UTF8 |
NLS_LANG 正確設定 (含語言、地區、字元集)CSALTER (僅限子集→超集) 或 UTF8 中介庫PROPS$, NLS_DATABASE_PARAMETERS)