在紅旗 Linux DC 5.0 (Asianux 2.0 核心) 上安裝 Oracle 10g R2 (10.2.0.1) 時,若資料庫字元集設定不當,中文資料插入後會全變成問號 (???)。本文記錄從字元集診斷到修正的完整過程。
INSERT 中文資料,查詢結果全為 ???。SELECT * FROM NLS_DATABASE_PARAMETERS 顯示 NLS_CHARACTERSET = WE8ISO8859P1 (西歐單位元組字元集,不支援中文)。ALTER DATABASE CHARACTER SET 改為 AMERICAN_AMERICA.US7ASCII (錯誤嘗試),問題依舊。WE8ISO8859P1、US7ASCII 均為單位元組字元集,無法儲存中文。ZHS16GBK (簡體中文雙位元組)、ZHT16BIG5 (繁體)、AL32UTF8 (Unicode UTF-8,推薦新專案)。CREATE DATABASE 時指定,建立後通常不可變更 (除非重建或使用昂貴的 CSALTER 工具)。EXPDP 匯出、冷備份檔案。SQL> SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER LIKE '%CHARACTERSET%';
PARAMETER VALUE
------------------------------ ----------------
NLS_CHARACTERSET AL32UTF8
NLS_NCHAR_CHARACTERSET AL16UTF16
SQL> CREATE TABLE test_ch (col1 VARCHAR2(20));
SQL> INSERT INTO test_ch VALUES ('中文測試');
SQL> SELECT * FROM test_ch;
COL1
-------------------
中文測試
資料庫字元集正確後,客戶端 NLS_LANG 必須匹配:
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8 (或 .ZHS16GBK)HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_... \NLS_LANG = AMERICAN_AMERICA.AL32UTF8NLS_LANG 格式:語言_地區.字元集。三者必須與資料庫端、作業系統區域設定一致,否則會發生隱性轉換導致資料損壞。
LANG=zh_CN.UTF-8 或 zh_TW.UTF-8,影響終端機顯示與排序,但不直接決定資料庫儲存編碼。字元集問題預防勝於治療:新專案初始規劃即確定字元集,文檔化、納入部署腳本、自動化驗證。