AL32UTF8 / UTF8NLS_LANG=.UTF8SQL*Plus **不支援自動字元集轉換**。當 NLS_LANG=.UTF8 時,Oracle Client 認為輸入已是 UTF-8,**不做轉換直接送往伺服器**。但實際輸入 (鍵盤/腳本檔) 是本地編碼 (GBK/Big5),伺服器按 UTF-8 解析 → 位元組流對不上 → 語法錯誤/亂碼。
SET NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK (Windows 簡中)
SET NLS_LANG=TRADITIONAL CHINESE_TAIWAN.ZHT16BIG5 (Windows 繁中)
SET NLS_LANG=AMERICAN_AMERICA.ZHS16GBK (Linux/Unix 常用)
此時 Client 會自動將 GBK/Big5 輸入轉為 UTF-8 送往伺服器,SQL 正常執行。
iconv -f GBK -t UTF-8 script.sql > script_utf8.sql (Linux)SPOOL result_utf8.lst
-- 執行查詢
SPOOL OFF
-- 再用 iconv/記事本 將 UTF-8 轉回本地編碼查看
或直接 IE 開啟 result_utf8.lst 選 UTF-8 瀏覽。
亂碼本質:**客戶端本地環境、客戶端 NLS_LANG、伺服器資料庫字元集** 三者不一致或錯誤。
-- 現象:資料庫字元集 US7ASCII,實際存 GBK 資料
-- 客戶端 NLS_LANG=US7ASCII → 單系統看似正常 (無轉換)
-- 跨系統/EXP/IMP → 亂碼爆發
-- 根因:Oracle 以為資料是 ASCII,按 ASCII→GBK 轉換邏輯處理實為 GBK 的位元組流
教訓:**絕不可用單位元組字元集儲存多位元組資料**。建庫時即選正確字元集,遷移用 DMU。
資料庫 AL32UTF8,客戶端 NLS_LANG=ZHS16GBK → 正常自動轉換
繁體 XP (ZHT16MSWIN950) → AL32UTF8 → 部分罕見字亂碼
→ 原因:Windows 缺字庫補丁,非 Oracle 問題,打補丁解決
此屬正常跨字元集轉換,**超集轉子集可能遺失字元**,子集轉超集安全。
LANG=zh_CN.GBK) 決定終端機顯示編碼NLS_LANG 決定 Oracle Client 轉換邏輯SQL*Plus、寫字板、記事本 (舊版)、**無自動編碼偵測/轉換功能** → 必須人工保證三者一致或用支援轉碼工具 (IE、VS Code、Notepad++、iconv) 中轉。
Windows **無原生 UTF-8 終端機** (Win 10 1903+ 可啟用 Beta: UTF-8 支援,但非預設)。設 NLS_LANG=.UTF8 並在 cmd/PowerShell 直接打中文,**必亂碼**,因終端機實際送出的是 GBK/Big5 位元組流。
| 現象 | 疑似成因 | 驗證指令 | 修正 |
|---|---|---|---|
| SQL*Plus 含中文 SQL 報錯 | NLS_LANG=.UTF8 但輸入非 UTF-8 | SELECT * FROM NLS_SESSION_PARAMETERS WHERE PARAMETER='NLS_LANG' | 設 NLS_LANG=本地編碼 或 腳本轉 UTF-8 |
| 查詢結果中文亂碼 | NLS_LANG 與終端機編碼不符 | chcp (Win) / locale (Linux) | 統一 NLS_LANG 與終端機代碼頁 |
| 跨系統 EXP/IMP 亂碼 | 源庫字元集設錯 (如 US7ASCII 存 GBK) | SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_CHARACTERSET' | DMU 遷移修正字元集 |
| 特定罕見字變 | 目標字元集無此字 (超集→子集) | 查字元集支援範圍 | 升級目標字元集 或 接受遺失 |
AL32UTF8 + 應用層轉碼**,NLS_LANG 設 .UTF8 (或 AL32UTF8)AL32UTF8,客戶端 NLS_LANG=本地編碼,利用資料庫自動轉換