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

Oracle 字符集、國家字符集與 NLS_LANG 運行時環境深度解析

     編輯:Oracle 教學

Oracle 字符集、國家字符集與 NLS_LANG 運行時環境深度解析

字符集問題是 Oracle 跨平台遷移、匯入匯出、應用連接最常見的隱形殺手。本文系統梳理:**資料庫字符集 vs 國家字符集**、**常見中文編碼演進**、**字符與編碼轉換實戰**、**NLS_LANG 三層結構對匯入匯出的決定性影響**,助您徹底搞懂字符集機制,避免亂碼災難。

一、兩大字符集架構:Database Character Set vs National Character Set

屬性資料庫字符集國家字符集
參數名NLS_CHARACTERSETNLS_NCHAR_CHARACTERSET
支援資料型別CHAR、VARCHAR2、CLOB、LONGNCHAR、NVARCHAR2、NCLOB
用途範圍表名、欄位名、PL/SQL 變數、SQL/PLSQL 原始碼儲存多語言 Unicode 資料儲存
典型值ZHS16GBK、AL32UTF8、WE8ISO8859P1AL16UTF16(預設)、UTF8
建立時指定CREATE DATABASE ... CHARACTER SET ZHS16GBKCREATE DATABASE ... NATIONAL CHARACTER SET AL16UTF16

鐵律:資料庫建立後**字符集不可變**(除非重建資料庫),國家字符集僅 10g+ 支援 ALTER DATABASE NATIONAL CHARACTER SET(有條件限制)。

二、Unicode 編碼方案與 Oracle 實作

  • UTF-8:變長 1-4 位元組,ASCII 相容,Web 標準 → Oracle AL32UTF8(完整 Unicode 6.0+)、UTF8(舊版 CESU-8,不推薦新建)
  • UTF-16:固定 2 或 4 位元組(代理對),Java/.NET 內部編碼 → Oracle AL16UTF16(大端序,國家字符集預設)
  • UCS-2:固定 2 位元組,僅支援 BMP 平面,已淘汰

三、常見中文編碼演進與對應 Oracle 字符集

標準年份覆蓋範圍Oracle 字符集位元組/字
GB2312-8019816763 漢字 + 682 符號ZHS16GBK2312802
GBK199521003 漢字 + 全中日韓統一表意文字ZHS16GBK2
GB180302000/2005全 Unicode,含少數民族字無直接對應(建議 AL32UTF8)1-4

關鍵差異:GBK 為 GB2312 超集,**同一碼位在 GB2312 與 GBK 可能對應不同漢字**(擴充區)。Oracle ZHS16GBK 實為 GBK 編碼,ZHS16GBK231280 嚴格對應 GB2312-80。

四、字符與編碼互轉實戰:DUMP / CHR / TO_NUMBER

-- 查看「蓋」字在資料庫字符集中的內部儲存碼位
SELECT DUMP('蓋') FROM dual;
-- 典型輸出:Typ=96 Len=2: 184,199  (ZHS16GBK 雙位元組)

-- 將十進制碼位轉十六進制
SELECT CONCAT(TO_CHAR(184,'xx'), TO_CHAR(199,'xx')) FROM dual;  -- B8 C7

-- 十六進制轉十進制驗證
SELECT TO_NUMBER('B8C7','xxxxxx') FROM dual;  -- 47303

-- 十進制碼位轉字符
SELECT CHR(47303) FROM dual;  -- 蓋(需 Session 字符集與資料庫一致)

應用場景**:排查亂碼根因、驗證匯入匯出字符集轉換正確性、編寫字符集轉換工具。

五、NLS_LANG:字符集轉換的「總開關」

結構定義

NLS_LANG = _.
   範例:AMERICAN_AMERICA.ZHS16GBK
         SIMPLIFIED CHINESE_CHINA.ZHS16GBK
         TRADITIONAL CHINESE_TAIWAN.ZHT16MSWIN950

三層作用機制

層級參數影響範圍
語言NLS_LANGUAGEOracle 錯誤訊息語言、月份/星期名稱、日期顯示格式
地區NLS_TERRITORY貨幣符號、數字格式(千分位/小數點)、週起始日、ISO 週年
字符集NLS_CHARACTERSET (Client)客戶端編碼宣告,決定「應用送出的位元組流」如何被 Oracle 解碼

匯入匯出字符集轉換鐵律

匯出時:NLS_LANG = 來源資料庫字符集 → 正確讀取來源資料位元組
匯入時:NLS_LANG = 來源資料庫字符集 → Oracle 自動將來源編碼轉換為**目標資料庫字符集**寫入

# 來源 DB: ZHS16GBK,目標 DB: AL32UTF8
# 匯出
export NLS_LANG=SIMPLIFIED_CHINESE_CHINA.ZHS16GBK
exp userid=... file=dump.dmp

# 匯入(關鍵:NLS_LANG 必須設為來源字符集,而非目標!)
export NLS_LANG=SIMPLIFIED_CHINESE_CHINA.ZHS16GBK
imp userid=... file=dump.dmp full=y

原理:匯入時 Oracle 讀取 DMP 檔案標記的來源字符集,對比 Client NLS_LANG 宣告的字符集,若一致則進行 **Server-side Conversion** 轉換為目標資料庫字符集。若 Client NLS_LANG 設為目標字符集(AL32UTF8),Oracle 認為無需轉換,直接寫入 UTF-8 位元組 → **亂碼入庫**。

六、NLS 運行庫路徑與 Locale Builder

  • 定義檔位置:$ORACLE_HOME/nls/data/
  • 中文定義檔:lx00023.nlb(簡體)、lx00024.nlb(繁體)
  • Locale Builder($ORACLE_HOME/bin/lbuilder)可視化編輯/建立自訂 Locale 定義

七、最佳實踐清單

  1. 新建資料庫:統一採用 AL32UTF8(資料庫字符集)+ AL16UTF16(國家字符集),全 Unicode 支援,零轉換損耗
  2. 應用層:JDBC/ODP.NET 等驅動**自動處理**字符集轉換,**勿手動設定 NLS_LANG 環境變數**干擾
  3. 傳統匯入匯出:嚴格遵循「匯入端 NLS_LANG = 來源資料庫字符集」鐵律
  4. Data Pump (expdp/impdp):伺服器端操作,**不受 Client NLS_LANG 影響**,首選遷移工具
  5. 混合字符集環境:建立字符集對照表,文件化每個資料庫/應用的字符集,變更前必做影響分析
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved