條件邏輯是 SQL 的核心,Oracle 提供 DECODE 函數與 CASE 表達式兩種機制。本文從底層實現、語法表達力、適用場景三個維度深度對比,給出明確選型建議。
| 特性 | DECODE | CASE |
|---|---|---|
| 編程範式 | Switch-Case 風格 | If-Else If-Else 風格 |
| 比較方式 | 僅支援等值匹配 | 支援任意布爾表達式 (>, <, BETWEEN, LIKE, IS NULL 等) |
| 返回類型 | 隱式類型轉換,以首個結果類型為準 | 嚴格類型一致性檢查 |
| NULL 語義 | DECODE(col, NULL, 'is null') 可匹配 NULL | 需顯式 WHEN col IS NULL |
-- DECODE 簡潔
SELECT DECODE(SIGN(5-5), 1, 'Positive', -1, 'Negative', 'Zero') FROM DUAL;
-- CASE 冗長
SELECT CASE SIGN(5-5) WHEN 1 THEN 'Positive' WHEN -1 THEN 'Negative' ELSE 'Zero' END FROM DUAL;
結論:等值匹配、分支少、邏輯簡單 → 優先用 DECODE,代碼更緊湊。
SELECT CASE
WHEN x_field < 40 THEN 'x_field < 40'
WHEN x_field < 50 THEN 'x_field < 50'
WHEN x_field < 60 THEN 'x_field < 60'
ELSE 'UNKNOWN'
END FROM DUAL;
DECODE 無法實現上述範圍邏輯,除非配合複雜嵌套/函數,可讀性極差。
-- DECODE 直接匹配 NULL
SELECT DECODE(comm, NULL, 'No Commission', comm) FROM emp;
-- CASE 需顯式 IS NULL
SELECT CASE WHEN comm IS NULL THEN 'No Commission' ELSE comm END FROM emp;
EXPLAIN PLAN 實測,通常 CASE 不劣於 DECODE| 場景 | 推薦 | 理由 |
|---|---|---|
| 離散值精確映射 (狀態碼、類型碼) | DECODE | 語法簡潔、可讀性高、NULL 友好 |
| 範圍/區間判斷 | CASE | 原生支援比較運算符 |
| 多條件組合 (AND/OR/NOT) | CASE | 邏輯表達直觀 |
| 嵌套條件邏輯 | CASE | 結構清晰,易維護 |
| 動態 SQL 生成 | CASE | 標準 SQL,跨庫遷移友好 |
| PL/SQL 過程式邏輯 | CASE 表達式/語句 | 支援 CASE ... WHEN ... THEN ... END CASE; 語句塊 |
-- 自定義排序
ORDER BY CASE status WHEN 'URGENT' THEN 1 WHEN 'HIGH' THEN 2 ELSE 3 END;
-- 條件聚合
SELECT
SUM(CASE WHEN sal > 3000 THEN 1 ELSE 0 END) AS high_sal_cnt,
SUM(CASE WHEN deptno = 10 THEN 1 ELSE 0 END) AS dept10_cnt
FROM emp;