Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> 關於 Linux

Linux 環境變數 LANG 與 NLS_LANG 區別深度解析:系統語系 vs Oracle 客戶端語系

編輯:關於 Linux

Linux 環境中 LANG 與 NLS_LANG 同樣包含「語言_地區.字元集」三要素,但作用層級、生效範圍、優先級完全不同。混淆兩者會導致系統介面語言正常但 Oracle 客戶端亂碼、或反之。本文深度對比兩者機制、設定方法、驗證方式與典型問題場景。

核心區別速查表

維度LANG (系統語系)NLS_LANG (Oracle 客戶端語系)
作用範圍整個 Linux 使用者空間 (Shell、GUI、C/Python/Go 程式等)僅 Oracle 客戶端工具 (sqlplus、exp/imp、rman、ODP.NET、JDBC Thin 等)
生效機制glibc locale 子系統、gettext 國際化框架Oracle NLS (National Language Support) 運行時庫
格式語言_地區.編碼 (如 zh_CN.UTF-8)語言_地區.字元集 (如 AMERICAN_AMERICA.ZHS16GBK)
字元集命名IANA/glibc 標準名 (UTF-8, GBK, GB2312)Oracle 專有名 (ZHS16GBK, AL32UTF8, ZHT16BIG5)
優先級受 LC_ALL、LC_* 覆蓋Oracle 客戶端唯一依據,不受系統 locale 影響
設定位置/etc/locale.conf、~/.bashrc、localectlShell 啟動腳本、.bash_profile、Oracle 用戶 .profile

LANG 詳細機制

Locale 分類 (LC_*)

locale
# LANG=zh_CN.UTF-8
# LC_CTYPE="zh_CN.UTF-8"      # 字元編碼/分類 (核心)
# LC_NUMERIC="zh_CN.UTF-8"    # 數字格式 (小數點、分組)
# LC_TIME="zh_CN.UTF-8"       # 日期時間格式
# LC_COLLATE="zh_CN.UTF-8"    # 排序規則
# LC_MONETARY="zh_CN.UTF-8"   # 貨幣格式
# LC_MESSAGES="zh_CN.UTF-8"   # 系統訊息語言
# LC_PAPER="zh_CN.UTF-8"      # 紙張尺寸
# LC_NAME="zh_CN.UTF-8"       # 姓名格式
# LC_ADDRESS="zh_CN.UTF-8"    # 地址格式
# LC_TELEPHONE="zh_CN.UTF-8"  # 電話格式
# LC_MEASUREMENT="zh_CN.UTF-8" # 度量衡
# LC_IDENTIFICATION="zh_CN.UTF-8"
# LC_ALL=                      # 未設定,否則覆蓋以上所有

關鍵: LC_CTYPE 決定字元編碼轉換,LC_MESSAGES 決定介面語言。若只想要中文介面但保持英文排序/數字格式:

export LANG=zh_CN.UTF-8
export LC_COLLATE=C
export LC_NUMERIC=C

NLS_LANG 詳細機制

三部分拆解

NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
# 語言    : AMERICAN (錯誤訊息、月份名稱等)
# 地區    : AMERICA  (日期格式、數字格式、貨幣符號)
# 字元集  : ZHS16GBK (簡體中文 GBK 編碼,16-bit)

Oracle 常用字元集對照

Oracle 字元集對應編碼說明
AL32UTF8UTF-8Unicode 完整支援,推薦新資料庫
ZHS16GBKGBK (CP936)簡體中文,含生僻字,Windows 相容
ZHS16CGB231280GB2312舊國標,字元較少
ZHT16BIG5Big5繁體中文
WE8ISO8859P1ISO-8859-1西歐語系,單位元組
UTF8UTF-8 (舊版)Oracle 8i/9i 版本,有缺陷,勿用

資料庫端字元集查詢

SELECT * FROM DATABASE_PROPERTIES
WHERE PROPERTY_NAME IN ('NLS_LANGUAGE','NLS_TERRITORY','NLS_CHARACTERSET');
# NLS_LANGUAGE: AMERICAN
# NLS_TERRITORY: AMERICA
# NLS_CHARACTERSET: AL32UTF8

典型問題場景與解決

場景一:系統中文正常,sqlplus 顯示亂碼

現象: LANG=zh_CN.UTF-8,但 sqlplus 查詢中文資料顯示亂碼/問號。

原因: NLS_LANG 未設或設錯 (如 AMERICAN_AMERICA.WE8ISO8859P1),Oracle 客戶端以單位元組編碼解讀 UTF-8 資料。

解決:

# 針對 AL32UTF8 資料庫
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
# 或簡體中文環境
export NLS_LANG=SIMPLIFIED CHINESE_CHINA.AL32UTF8

# 永久生效:加入 oracle 用戶 ~/.bash_profile

場景二:exp/imp 導出導入中文損壞

原因: 導出時 NLS_LANG 與資料庫字元集不匹配,導致字元集轉換錯誤。

鐵律: 導出/導入時 NLS_LANG 必須與資料庫 NLS_CHARACTERSET 完全一致。

# 資料庫為 ZHS16GBK
export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
exp userid=system/pass file=dump.dmp full=y

# 資料庫為 AL32UTF8
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
imp userid=system/pass file=dump.dmp full=y

場景三:JDBC Thin 驅動不受 NLS_LANG 影響

JDBC Thin 為純 Java 實現,使用 JVM file.encoding (受 LANG/LC_CTYPE 影響) 而非 NLS_LANG。需確保:

-Dfile.encoding=UTF-8
# 連線屬性
oracle.jdbc.defaultNChar=true  # 正確處理 NCHAR/NVARCHAR2

最佳實踐配置範本

# ~/.bash_profile (Oracle 專用用戶 oracle)
# === 系統語系 ===
export LANG=en_US.UTF-8          # 系統介面保持英文,利於排錯
export LC_CTYPE=en_US.UTF-8      # 編碼 UTF-8
export LC_MESSAGES=en_US.UTF-8

# === Oracle 客戶端語系 ===
# 根據目標資料庫字元集設定,範例為 AL32UTF8
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8

# === 其他 Oracle 環境 ===
export ORACLE_HOME=/u01/app/oracle/product/19c/dbhome_1
export PATH=$ORACLE_HOME/bin:$PATH
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH

驗證清單

檢查項命令預期
系統 LocalelocaleLANG/LC_CTYPE 為 UTF-8
NLS_LANG 環境變數echo $NLS_LANG與目標 DB 字元集一致
sqlplus 連線測試sqlplus user/pass@db中文查詢/插入正常
資料庫字元集SQL 查詢 NLS_CHARACTERSET與 NLS_LANG 字元集部分一致

明確區分 LANG (系統級) 與 NLS_LANG (Oracle 客戶端級),並根據資料庫字元集精確設定 NLS_LANG,是避免 Oracle 中文亂碼、導出導入損壞的核心鑰匙。

Copyright © Windows教程網 All Rights Reserved