首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle 字符集完整指南:概念、NLS_LANG 三要素、Server/Client/DMP 三端查看與修改實戰

     編輯:Oracle 資料庫基礎

Oracle 字符集核心知識體系與實操手冊

字符集問題是 Oracle 遷移、匯入匯出、亂碼排查的核心。本文系統整理:字符集定義、NLS_LANG 三要素、Server/Client/DMP 三端字符集查看方法、修改策略 (只能擴大不能縮小)、導入導出一致性原則。

什麼是 Oracle 字符集

  • 定義:位元組資料 → 字元符號的映射集合,有大小與包含關係
  • 核心參數:NLS_LANG = LANGUAGE_TERRITORY.CHARACTERSET
    • LANGUAGE:訊息語言 (如 AMERICAN)
    • TERRITORY:日期/數字格式 (如 AMERICA)
    • CHARACTERSET:唯一影響資料儲存與解讀 (如 ZHS16GBK, AL32UTF8)
  • 兩資料庫 CHARACTERSET 相同即可相互導入導出;前兩項僅影響介面語言

三端字符集查看方法

四種 NLS 參數視圖差異


-- 1. 資料庫層級 (實際儲存字符集)
SELECT * FROM NLS_DATABASE_PARAMETERS;  -- 來源:PROPS$

-- 2. 實例層級 (參數檔/環境變數/註冊表)
SELECT * FROM NLS_INSTANCE_PARAMETERS;  -- 來源:V$PARAMETER

-- 3. 會話層級 (當前會話生效設定)
SELECT * FROM NLS_SESSION_PARAMETERS;   -- 來源:V$NLS_PARAMETERS

-- 4. 會話級動態修改
ALTER SESSION SET NLS_LANGUAGE = 'AMERICAN';
ALTER SESSION SET NLS_TERRITORY = 'AMERICA';
-- 字符集不可在會話層級修改!

優先順序:ALTER SESSION > 環境變數 > 註冊表 > 參數檔。字符集必須一致,語言/地區可不同 (建議用英文避免錯誤訊息編碼問題)。

修改資料庫字符集:只能擴大不能縮小


-- 必須關閉資料庫,以 RESTRICTED 模式啟動
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER SYSTEM ENABLE RESTRICTED SESSION;
ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
ALTER DATABASE OPEN;
ALTER DATABASE CHARACTER SET AL32UTF8;  -- 目標必須為原字符集的超集
  • 超集原則:US7ASCII ⊂ WE8ISO8859P1 ⊂ ZHS16GBK ⊂ AL32UTF8
  • ZHS16GBK → ZHS16CGB231280 不可行 (非超集關係)
  • 若需縮小字符集:只能重建資料庫 + EXPDP/IMPDP

導入導出字符集一致性鐵律

  1. DMP 檔字符集 = 匯出時 Server 字符集 (由 EXP 寫入檔頭)
  2. 匯入時:Client NLS_LANG 必須 = DMP 字符集 = 目標 Server 字符集
  3. 三者一致 → 正確導入;任何一端不一致 → 亂碼或報錯 (ORA-02374, ORA-12899)

實戰排查清單

  1. 查詢三端字符集是否一致
  2. 若 Client ≠ Server:修改 Client 環境變數/註冊表
  3. 若 DMP ≠ 目標 Server:檢查是否為超集關係,否則需轉碼或重建庫
  4. 新專案強制統一 AL32UTF8,避免所有字符集痛點
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
端別查看方法範例輸出
Server (資料庫)SELECT USERENV('LANGUAGE') FROM DUAL;
SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_CHARACTERSET';
AMERICAN_AMERICA.ZHS16GBK
Client (用戶端)Windows:註冊表 HKLM\SOFTWARE\ORACLE\KEY_\NLS_LANG
Linux/Unix:echo $NLS_LANG
臨時設定:SET NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
SIMPLIFIED CHINESE_CHINA.ZHS16GBK
DMP 匯出檔小檔:UltraEdit 開啟 16 進制看第 2-3 位元組 (如 0354)
大檔:cat exp.dmp | od -x | head -1 | awk '{print $2$3}' | cut -c3-6
解碼:SELECT NLS_CHARSET_NAME(TO_NUMBER('0354','XXXX')) FROM DUAL;
ZHS16GBK