DECODE(expr, search1, result1, search2, result2, ..., default)
expr 與 searchN,相等則回傳對應 resultNsearchN 未匹配時回傳 default (可省略,預設 NULL)switch-case 但無 break,僅單一匹配| 特性 | DECODE | CASE |
|---|---|---|
| 語法風格 | 函數式、簡潔 | 陳述式、可讀性佳 |
| 比較類型 | 僅等值比較 | 支援範圍、IN、LIKE、IS NULL 等 |
| NULL 處理 | NULL = NULL 視為匹配 | NULL = NULL 為 UNKNOWN,需 IS NULL |
| 回傳型別 | 隱式轉換所有 result | 同上,但可明確 CAST |
| 效能 | 相同 (內部轉為 CASE) | 相同 |
| 適用場景 | 簡單等值映射、舊代碼維護 | 複雜邏輯、新代碼首選 |
SELECT id,
DECODE(status, 'A', 'Active', 'I', 'Inactive', 'P', 'Pending', 'Unknown') AS status_desc
FROM orders;
SELECT DECODE(flag, 'Y', 'Yes', 'N', 'No', NULL, 'Not Set', 'Default')
FROM test_table;
-- flag 為 NULL 時回傳 'Not Set',DECODE 視 NULL=NULL 為真
CASE 寫法需額外處理:CASE WHEN flag IS NULL THEN ... WHEN flag = 'Y' THEN ...
SELECT DECODE(SIGN(score - 60), -1, 'Fail', 0, 'Pass', 1, 'Pass')
FROM students;
-- SIGN 回傳 -1/0/1,巧妙實現範圍判斷
-- oper_flag 為 VARCHAR2,但資料混含 '1'、'0'、'失敗'
SELECT DECODE(oper_flag, 1, '成功', '失敗') FROM sec_log_operation;
-- ORA-01722: invalid number
-- 原因:1 為 NUMBER,Oracle 嘗試將 oper_flag 隱式轉 NUMBER,遇 '失敗' 失敗
SELECT DECODE(oper_flag, '1', '成功', '失敗') FROM sec_log_operation;
-- 所有 search 值加引號,強制字串比較,避免隱式轉換
SELECT DECODE(dept_id,
10, DECODE(job_id, 'CLERK', 'Admin-Clerk', 'Mgr', 'Admin-Mgr', 'Admin-Other'),
20, DECODE(job_id, 'CLERK', 'Sales-Clerk', 'Sales-Other'),
'Other-Dept'
) FROM employees;
SELECT
COUNT(DECODE(status, 'A', 1)) AS active_cnt,
COUNT(DECODE(status, 'I', 1)) AS inactive_cnt,
SUM(DECODE(type, 'PREMIUM', amount, 0)) AS premium_revenue
FROM orders;
-- DECODE 回傳非 NULL 即被 COUNT 計數,回傳 0 參與 SUM
SELECT * FROM products
ORDER BY DECODE(:sort_by, 'PRICE', price, 'NAME', name, 'DATE', create_date);
TO_NUMBER/TO_DATE 避免隱式轉換
-- DECODE 版
SELECT DECODE(grade, 'A', 'Excellent', 'B', 'Good', 'C', 'Fair', 'Poor') FROM students;
-- CASE 版 (推薦)
SELECT CASE grade
WHEN 'A' THEN 'Excellent'
WHEN 'B' THEN 'Good'
WHEN 'C' THEN 'Fair'
ELSE 'Poor'
END
FROM students;
-- 條件複雜時 CASE 必勝
SELECT CASE
WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN 'B'
WHEN score >= 70 THEN 'C'
ELSE 'F'
END
FROM students;
DECODE 是 Oracle 早期特有的簡潔條件函數,雖然功能被 CASE 涵蓋並超越,但其「NULL=NULL 匹配」特性在特定場景 (如狀態碼含 NULL) 仍具優勢。現代開發建議:新代碼用 CASE,維護舊代碼時理解 DECODE 行為即可。