INSTR 是 Oracle 字符串處理的基石函數,用於**查找子串在源字符串中的位置**,返回數值型位置(1 基礎),未找到返回 0。廣泛應用於條件判斷、字符串解析、數據清洗等場景。
INSTR( source_string, search_string [, start_position [, occurrence ] ] )
| 參數 | 類型 | 默認值 | 說明 |
|---|---|---|---|
| source_string | VARCHAR2/CLOB | - | 被搜索的源字符串 |
| search_string | VARCHAR2/CLOB | - | 要查找的目標子串 |
| start_position | NUMBER | 1 | 起始搜索位置:正數從左向右,負數從右向左(絕對值為位置) |
| occurrence | NUMBER | 1 | 查找第 N 次出現(必須 > 0) |
| start_position | occurrence | 搜索方向 | 返回值含義 |
|---|---|---|---|
| 1 (默認) | 1 (默認) | 左→右 | 首次出現的起始位置 |
| 3 | 1 | 左→右 | 從第 3 字符開始,首次出現位置 |
| 1 | 2 | 左→右 | 第 2 次出現的起始位置 |
| -1 | 1 | 右→左 | 從末尾向前,首次出現的起始位置 |
| -3 | 2 | 右→左 | 從倒數第 3 字符向前,第 2 次出現位置 |
-- 基礎查找
SELECT INSTR('syranmo', 's') FROM dual; -- 1
SELECT INSTR('syranmo', 'ra') FROM dual; -- 3
-- 多次出現查找
SELECT INSTR('syran mo', 'a', 1, 2) FROM dual; -- 0 (只有1個'a')
SELECT INSTR('abacada', 'a', 1, 3) FROM dual; -- 5 (第3個'a'在位置5)
-- 反向查找
SELECT INSTR('syranmo', 'an', -1, 1) FROM dual; -- 4 (從右向左找'an',位置仍為4)
-- 未找到情況
SELECT INSTR('abc', 'd') FROM dual; -- 0
-- 空字符串處理
SELECT INSTR('', ',') FROM dual; -- NULL (源串為空返回NULL,非0)
-- 傳統寫法:動態拼接 SQL,有注入風險、難複用執行計劃
WHERE code IN ('A10001','A10002')
-- INSTR 寫法:單一 SQL,參數化傳入字符串
WHERE INSTR('A10001,A10002', code) > 0
-- 性能提示:對 code 列創建索引,優化器可使用 INDEX RANGE SCAN
-- 等價於 code LIKE '%001%'
WHERE INSTR(code, '001') > 0
-- 優勢:INSTR 可用於函數索引,LIKE '%...%' 無法使用普通索引
CREATE INDEX idx_code_instr ON emp (INSTR(empno, '001'));
-- 結合 SUBSTR 實現字段提取
-- 字符串格式:'PROD_12345_CAT_ELECTRONICS'
SELECT
SUBSTR(str, 1, INSTR(str, '_') - 1) AS prefix, -- PROD
SUBSTR(str, INSTR(str, '_') + 1, INSTR(str, '_', 1, 2) - INSTR(str, '_') - 1) AS id, -- 12345
SUBSTR(str, INSTR(str, '_', 1, 3) + 1) AS suffix -- ELECTRONICS
FROM dual;
-- 檢查字段是否包含非法字符
SELECT * FROM customer
WHERE INSTR(name, '<') > 0
OR INSTR(name, '>') > 0
OR INSTR(name, '&') > 0;
DECLARE
v_pos NUMBER;
BEGIN
v_pos := INSTR('', ',');
IF v_pos IS NULL THEN
DBMS_OUTPUT.PUT_LINE('源字符串為空,返回 NULL');
END IF;
END;
規則:source_string 為空字符串 '' 時返回 NULL,而非 0。
INSTR 區分大小寫。不區分大小寫查找需轉換:
WHERE INSTR(UPPER(source), UPPER(search)) > 0
返回值為**字符位置**(非字節位置),AL32UTF8 等多字節字符集下每個漢字佔 1 位置、3 字節。
CREATE INDEX idx ON t(INSTR(col, 'key'));SUBSTR(col,1,n) = 'prefix' 可利用普通索引| 函數 | 用途 | 返回值 | 典型場景 |
|---|---|---|---|
| INSTR | 查找子串位置 | NUMBER | 條件判斷、解析定位 |
| SUBSTR | 截取子串 | VARCHAR2 | 字段提取、格式化 |
| REPLACE | 替換子串 | VARCHAR2 | 數據清洗、脫敏 |
| REGEXP_INSTR | 正則表達式查找 | NUMBER | 複雜模式匹配 |