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

Oracle 字符集轉換深度解析:從網絡包看亂碼產生與解決之道

     編輯:Oracle 資料庫基礎

字符集轉換發生在哪裡?

  • 普通字符串 (VARCHAR2/CHAR):客戶端 OCI Library 根據 NLS_LANG 轉換為資料庫字符集,再傳給 Server。
  • 國家字符串 (NVARCHAR2/NCHAR):雙重轉換 —— 客戶端先按 NLS_LANG 轉為資料庫字符集,Server 再按 NLS_NCHAR_CHARACTERSET 轉為國家字符集。

實測驗證:網絡包攔截分析

環境:資料庫 ZHS16GBK / 國家字符集 AL16UTF16

客戶端 NLS_LANG插入 '中'網絡包編碼結果
未設定 (預設 ZHS16GBK)INSERT '中'D6 D0 (GBK)正確
AMERICAN_AMERICA.US7ASCIIINSERT '中'3F 3F (??)亂碼:US7ASCII 無法表達中文
SIMPLIFIED CHINESE_CHINA.ZHS16CGB231280INSERT '中'D6 D0正常 (GBK/GB2312 相容)
同上INSERT '喫' (生僻字)ORA-01756客戶端轉換失敗,誤判引號結束

國家字符集雙重轉換陷阱

資料庫 US7ASCII / 國家字符集 AL16UTF16,客戶端 US7ASCII 插入 '中':

  • 客戶端不轉換(字符集一致),傳送 D6 D0(但 US7ASCII 視為兩字節 0xD6, 0xD0)。
  • Server 將 NVARCHAR2 列從 US7ASCII 轉 AL16UTF16:高位截斷 → 0x56 0x50 ('VP')。
  • 查詢顯示 VP 而非 中。

結論:資料庫字符集若為單字節集,國家字符集轉換極易出錯,建議資料庫字符集採用多字節集 (如 AL32UTF8/ZHS16GBK)。

查詢時的字符集轉換

  • Server 原編碼回傳資料,附帶字符集 ID (如 0x0354=ZHS16GBK, 0x07D0=AL16UTF16)。
  • 客戶端 OCI 依 NLS_LANG (普通列) 與 NLS_NCHAR (國家列) 決定是否轉換。
  • 未設 NLS_NCHAR 時預設等於 NLS_LANG 字符集部分。

EXP/IMP 亂碼特殊現象

現象:資料正常,但表/列註釋、中文列名、PL/SQL 內中文變亂碼。

原因:DMP 檔案內部結構中,DDL 與註釋以 NLS_LANG 指定字符集寫入,若匯出/匯入端 NLS_LANG 不一致,導致這部分解碼錯誤,而資料區塊因標記了字符集 ID 可正確轉換。

對策:匯出匯入雙端統一 NLS_LANG 為資料庫字符集 (如 ZHS16GBK),或使用 Data Pump (expdp/impdp) 避免客戶端轉換層。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved