首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 教學

Oracle 字符串分割利器:自定義 SPLIT 與 SPLITSTR 函數完整實現

     編輯:Oracle 教學

設計目標

  • SPLIT(str, sep):返回集合型別,可用於 TABLE() 轉行,支援 IN 子查詢。
  • SPLITSTR(str, idx, sep):取第 N 個分割片段,idx=0 返回原串,越界返回 NULL。

型別與函數定義

-- 1. 集合型別
CREATE OR REPLACE TYPE tabletype AS TABLE OF VARCHAR2(32767);

-- 2. SPLIT:PIPELINED 流式返回,記憶體友好
CREATE OR REPLACE FUNCTION split(
    p_list CLOB,
    p_sep  VARCHAR2 DEFAULT ','
) RETURN tabletype PIPELINED IS
    l_idx   PLS_INTEGER;
    v_list  VARCHAR2(32767) := p_list;
BEGIN
    LOOP
        l_idx := INSTR(v_list, p_sep);
        IF l_idx > 0 THEN
            PIPE ROW (SUBSTR(v_list, 1, l_idx - 1));
            v_list := SUBSTR(v_list, l_idx + LENGTH(p_sep));
        ELSE
            PIPE ROW (v_list);
            EXIT;
        END IF;
    END LOOP;
    RETURN;
END;
/

-- 3. SPLITSTR:調用 SPLIT 復用邏輯
CREATE OR REPLACE FUNCTION splitstr(
    str IN CLOB,
    i   IN NUMBER DEFAULT 0,
    sep IN VARCHAR2 DEFAULT ','
) RETURN VARCHAR2 IS
    t_cnt NUMBER;
    t_str VARCHAR2(4000);
BEGIN
    IF i = 0 THEN
        RETURN str;
    ELSIF INSTR(str, sep) = 0 THEN
        RETURN NULL;  -- 原邏輯返回 sep,這裡改為 NULL 更符合直覺
    ELSE
        SELECT COUNT(*) INTO t_cnt FROM TABLE(split(str, sep));
        IF i <= t_cnt THEN
            SELECT column_value INTO t_str
            FROM (SELECT ROWNUM rn, column_value FROM TABLE(split(str, sep)))
            WHERE rn = i;
        END IF;
    END IF;
    RETURN t_str;
END;
/

使用示例

1. SPLIT 配合 TABLE() 轉行

SELECT * FROM TABLE(split('a,b,c,e,d,f,g'));
-- 返回 7 行,每行一個元素

SELECT * FROM TABLE(split('X-rapido&Lemon', '&'));
-- 自定義分隔符

SPLIT 結果集

展開集合

2. 實戰:IN 子查詢動態列表

SELECT * FROM users
WHERE user_id IN (SELECT column_value FROM TABLE(split('1001,1002,1003')));

3. SPLITSTR 取指定片段

SELECT splitstr('X-rapido&Lemon&Jennifer', 1, '&') FROM dual; -- X-rapido
SELECT splitstr('X-rapido&Lemon&Jennifer', 2, '&') FROM dual; -- Lemon
SELECT splitstr('X-rapido&Lemon&Jennifer', 3, '&') FROM dual; -- Jennifer
SELECT splitstr('X-rapido&Lemon&Jennifer', 4, '&') FROM dual; -- NULL

性能與避坑提示

  • PIPELINED:逐行產出,避免大集合佔用 PGA。
  • VARCHAR2(32767):支援最大長度,超長字串請用 CLOB 參數。
  • 分隔符支援多字符 (如 '||'),INSTR/LENGTH 自動適配。
  • 12c+ 可考慮內建 JSON_TABLE 或 XMLTABLE 替代。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved