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

Oracle字串分割三種實作方案:自訂函數、PIPELINED、REGEXP_CONNECT BY對比

     編輯:Oracle 資料庫基礎

從傳統集合函數到正則遞歸查詢,三種字串分割技術完整對比

Oracle無內建SPLIT,常見三種實作路徑各有優劣。本文提供完整代碼、效能特性與選型建議。

方案一:傳統集合型別函數(非PIPELINED)


CREATE OR REPLACE TYPE str_split AS TABLE OF VARCHAR2(4000);
/
CREATE OR REPLACE FUNCTION splitstr(p_string VARCHAR2, p_delimiter VARCHAR2)
RETURN str_split
AS
  v_list str_split := str_split();
  v_start NUMBER := 1;
  v_pos   NUMBER;
BEGIN
  LOOP
    v_pos := INSTR(p_string, p_delimiter, v_start);
    IF v_pos = 0 THEN
      v_list.EXTEND;
      v_list(v_list.COUNT) := SUBSTR(p_string, v_start);
      EXIT;
    ELSE
      v_list.EXTEND;
      v_list(v_list.COUNT) := SUBSTR(p_string, v_start, v_pos-v_start);
      v_start := v_pos + 1;
    END IF;
  END LOOP;
  RETURN v_list;
END;
/
-- 使用:SELECT * FROM TABLE(splitstr('a,b,c', ','));
  • 優點:邏輯直觀、相容舊版本
  • 缺點:需完整構建集合再返回,記憶體佔用大、無法流式處理

方案二:PIPELINED函數(流式輸出,推薦)


CREATE OR REPLACE TYPE str_split AS TABLE OF VARCHAR2(4000);
/
CREATE OR REPLACE FUNCTION splitstr_pipe(p_string VARCHAR2, p_delimiter VARCHAR2)
RETURN str_split PIPELINED
AS
  v_len   NUMBER := LENGTH(p_string);
  v_start NUMBER := 1;
  v_pos   NUMBER;
BEGIN
  WHILE v_start <= v_len LOOP
    v_pos := INSTR(p_string, p_delimiter, v_start);
    IF v_pos = 0 THEN
      PIPE ROW(SUBSTR(p_string, v_start));
      EXIT;
    ELSE
      PIPE ROW(SUBSTR(p_string, v_start, v_pos-v_start));
      v_start := v_pos + 1;
    END IF;
  END LOOP;
  RETURN;
END;
/
-- 使用:SELECT * FROM TABLE(splitstr_pipe('a,b,c', ','));
  • 優點:逐行產出,低記憶體、可管道化並行、支援FETCH FIRST N ROWS提前終止
  • 缺點:需PIPELINED關鍵字,10g+支援

方案三:REGEXP_SUBSTR + CONNECT BY(純SQL,無需建立物件)


SELECT DBMS_LOB.SUBSTR(
         REGEXP_SUBSTR('abc,def,ggg,1,2,3,4,5', '[^,]+', 1, x.n)
       ) AS token
FROM DUAL,
     (SELECT ROWNUM n FROM DUAL CONNECT BY ROWNUM <= 100) x
WHERE REGEXP_SUBSTR('abc,def,ggg,1,2,3,4,5', '[^,]+', 1, x.n) IS NOT NULL;
  • 優點:零物件部署、臨時查詢極便利、正則表達式靈活支援多字元分隔符
  • 缺點:CONNECT BY遞歸有上限(預設100/最大MAX_RECURSION_DEPTH)、大量資料效能較差
  • 關鍵點:'[^,]+' 為「非逗號字元一或多個」;ROWNUM <= 100 限制最大分割段數

效能與選型建議

場景推薦方案理由
PL/SQL程式內部頻繁呼叫PIPELINED函數效能最佳、記憶體可控、可並行
臨時SQL/報表/一次性分析REGEXP + CONNECT BY免部署、正則強大、可讀性高
舊版本(9i-) / 簡單邏輯傳統集合函數相容性最好
大量資料(>10萬段)分割PIPELINED + 並行流式處理避免OOM

12c/19c 新選項

  • JSON_TABLE:將JSON陣列轉關聯行
  • XMLTABLE:XML路徑提取
  • LISTAGG逆向操作(行轉字串)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved