函數語法
SUBSTR(string, start_position [, length ])
參數說明
string:來源字串
start_position:起始位置 從 1 開始計算(非 0),負數表示從尾部倒數
length:截取長度(可選),省略則截取至字串末尾
重要:Oracle SUBSTR 起始位置以 1 為基底,這與多數程式語言(C、Java、Python 以 0 為基底)不同,極易踩坑。
核心範例
| 呼叫 | 結果 | 說明 |
SUBSTR('ABCDEFG', 1)ABCDEFG | 從第 1 字元截取至結尾 |
SUBSTR('ABCDEFG', 3)CDEFG | 從第 3 字元 (C) 截取至結尾 |
SUBSTR('ABCDEFG', 1, 3)ABC | 從第 1 字元截取 3 個字元 |
SUBSTR('ABCDEFG', -3)EFG | 倒數第 3 字元 (E) 至結尾 |
SUBSTR('ABCDEFG', -5, 2)CD | 倒數第 5 字元 (C) 開始截取 2 個 |
SUBSTR('ABCDEFG', 1, 100)ABCDEFG | 長度超出不報錯,實際截取至結尾 |
常見變體函數
SUBSTRB:以 位元組 為單位計算位置/長度(適用多位元組字符集)
SUBSTRC:以 完整 Unicode 字元 為單位(補充字元處理)
SUBSTR2:以 UCS-2 代碼單元 為單位
SUBSTR4:以 UCS-4 代碼點 為單位
實戰應用場景
1. 固定寬度欄位解析(如 ETL 匯入)
SELECT SUBSTR(record, 1, 10) AS id,
SUBSTR(record, 11, 20) AS name,
SUBSTR(record, 31, 8) AS birth_date,
SUBSTR(record, 39) AS address
FROM staging_table;
2. 遮罩敏感資料(手機、身分證)
SELECT 'XXX-XXX-' || SUBSTR(phone, -4) AS masked_phone,
SUBSTR(id_no, 1, 1) || '********' || SUBSTR(id_no, -1) AS masked_id
FROM customers;
3. 搭配 INSTR 進行動態截取
-- 取得 @ 之前的部份 (Email 帳號)
SELECT SUBSTR(email, 1, INSTR(email, '@') - 1) AS account
FROM users;
-- 取得最後一個 / 之後的檔名
SELECT SUBSTR(path, INSTR(path, '/', -1) + 1) AS filename
FROM file_logs;
4. 分頁顯示長文本摘要
SELECT CASE
WHEN LENGTH(content) > 200
THEN SUBSTR(content, 1, 200) || '...'
ELSE content
END AS summary
FROM articles;
效能提示
- SUBSTR 為內建函數,極度優化,無顯著效能負擔
- 避免在 WHERE 條件對大欄位使用 SUBSTR 導致全表掃描,考慮函數索引:
CREATE INDEX idx_substr ON t(SUBSTR(col,1,10))
- 大量資料處理時,PL/SQL 批次處理優於逐筆 SQL
相關函數速查