NLS 參數三大層級
| 層級 | 範圍 | 優先順序 | 設定方式 |
| 資料庫 | 全域預設 | 最低 | 建庫時指定、NLS_DATABASE_PARAMETERS |
| Session | 當前連線 | 中 | ALTER SESSION SET NLS_...、客戶端環境變數 |
| SQL 函數 | 單一函數呼叫 | 最高 | TO_CHAR(..., 'NLS_DATE_LANGUAGE=AMERICAN') |
核心 NLS 參數速查
| 參數 | 用途 | 常見值範例 |
| NLS_LANGUAGE | 訊息語言、月份/星期名稱 | AMERICAN, TRADITIONAL CHINESE, SIMPLIFIED CHINESE |
| NLS_TERRITORY | 區域慣例 (貨幣、週起始日、數字格式) | AMERICA, TAIWAN, CHINA |
| NLS_CHARACTERSET | 資料庫字符集 (建庫後不可變) | AL32UTF8, ZHS16GBK, WE8MSWIN1252 |
| NLS_NCHAR_CHARACTERSET | 國家字符集 (NCHAR/NVARCHAR2) | AL16UTF16, UTF8 |
| NLS_DATE_FORMAT | 預設日期顯示格式 | YYYY-MM-DD, DD-MON-RR, RRRR/MM/DD |
| NLS_TIMESTAMP_FORMAT | 預設時間戳格式 | YYYY-MM-DD HH24:MI:SS.FF |
| NLS_NUMERIC_CHARACTERS | 小數點/群組分隔符 | '.,' (美制) 、',.' (歐制) |
| NLS_SORT | 排序規則 | BINARY, LINGUISTIC (如 SCHINESE_RADICAL_M) |
| NLS_COMP | 比較語義 | BINARY, LINGUISTIC |
| NLS_LENGTH_SEMANTICS | VARCHAR2 長度單位 | BYTE (預設), CHAR |
實戰查詢與設定
1. 查詢資料庫級參數
SELECT * FROM nls_database_parameters;
SELECT * FROM v$nls_valid_values WHERE parameter = 'CHARACTERSET' ORDER BY value;
2. 查詢 Session 級參數
SELECT * FROM nls_session_parameters;
3. 修改 Session 參數
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
ALTER SESSION SET NLS_SORT = 'SCHINESE_PINYIN_M';
ALTER SESSION SET NLS_COMP = 'LINGUISTIC';
字符集選型指南
| 字符集 | 類型 | 支援範圍 | 適用場景 |
| AL32UTF8 | Unicode UTF-8 | 所有語言、Emoji、補充字元 | 新建系統首選、多語言、雲端部署 |
| ZHS16GBK | 簡體中文擴充 | 中文、英文、部分符號 | 舊系統、純中文環境 |
| ZHT16MSWIN950 | 繁體中文 Big5 | 繁中、英文 | 台灣舊系統 |
| AL16UTF16 | UTF-16BE | 所有語言 | NCHAR/NVARCHAR2 國家字符集 |
| WE8MSWIN1252 | 西歐單位元組 | 西歐語系 | 純英文/西歐舊系統 |
警告:資料庫字符集建庫後不可變更 (需重建遷移)。新專案強烈建議 AL32UTF8。
排序規則深度解析
BINARY vs LINGUISTIC
- BINARY:按編碼值排序,效能最好,但 'a' > 'Z' (ASCII 碼順序)
- LINGUISTIC:按語言規則排序,如拼音、筆畫、字典序
常用中文排序
| 排序名稱 | 規則 | 適用 |
| SCHINESE_PINYIN_M | 漢語拼音 (含聲調) | 通用中文排序 |
| SCHINESE_RADICAL_M | 部首筆畫 | 字典、索引 |
| SCHINESE_STROKE_M | 筆畫數 | 筆順教學 |
| TRADITIONAL_CHINESE | 繁體中文預設 | 台灣/港澳環境 |
啟用語言排序
-- Session 級
ALTER SESSION SET NLS_SORT = 'SCHINESE_PINYIN_M';
ALTER SESSION SET NLS_COMP = 'LINGUISTIC';
-- 單一查詢 (最高優先級)
SELECT * FROM products
ORDER BY NLSSORT(name, 'NLS_SORT=SCHINESE_PINYIN_M');
-- 建立語言索引 (加速 ORDER BY)
CREATE INDEX idx_products_name_ling ON products
(NLSSORT(name, 'NLS_SORT=SCHINESE_PINYIN_M'));
日期格式最佳實務
- 永遠在應用層明確格式化:Java
DateTimeFormatter、C# ToString("yyyy-MM-dd")
- 資料庫層避免依賴 NLS_DATE_FORMAT:不同 Session 可能不同,導致 Bug
- 跨系統整合用 ISO 8601:
YYYY-MM-DDTHH24:MI:SS
- PL/SQL 內部處理用 DATE/TIMESTAMP 型別,勿轉字串運算
常見問題排查
| 現象 | 可能原因 | 解決 |
| 中文亂碼 | Client/DB 字符集不匹配 | 統一 AL32UTF8、檢查 NLS_LANG 環境變數 |
| 排序順序錯誤 | NLS_SORT=BINARY | 設定 LINGUISTIC 排序、建語言索引 |
| 日期插入失敗 | 格式不匹配 NLS_DATE_FORMAT | 用 TO_DATE('2024-01-15','YYYY-MM-DD') 明確格式 |
| 數字分組符錯誤 | NLS_NUMERIC_CHARACTERS | 明確 TO_CHAR(num, '999G999D00', 'NLS_NUMERIC_CHARACTERS='',.''') |
NLS 參數是 Oracle 國際化的核心。理解「三層級優先順序」、選對字符集 (AL32UTF8)、善用語言排序與語言索引、在應用層明確格式化,能避開 90% 的國際化坑點。建議專案建立 NLS 設定標準文件,納入代碼審查清單。
- 上一篇文章: Oracle DECODE 函數完整指南:語法、與 CASE 對比、資料型別陷阱與實戰範例
- 下一篇文章: Oracle RAC OCR 鏡像管理實戰:新增、替換與刪除完整操作指南
Copyright ©
程式碼之家 All Rights Reserved