Oracle 字符串分割函數 splitstr 和 splitstrbyseparators


本文內容

  • 演示字符串分割
  • 數據結構——字符數組
  • 字符串分割函數 PL/SQL 包
  • 結果

 

演示字符串分割

本文字符串分割函數能達到如下效果,這是用 SELECT 語句查看結果,在“結論”小節,將用過程查看分割的結果:

select strutil.concat(strutil.splitstr('a,1,b,2,ccdd;ef;')) as split1,
       strutil.concat(strutil.splitstrbyseparators('a,1,b,2,ccdd;ef;', ',')) as split2,
       strutil.concat(strutil.splitstrbyseparators('a,1,b,2,ccdd;ef;', ',;')) as split3,
       strutil.concat(strutil.splitstrbyseparators('a,1,b,2,;|\;ef;', ',;|\')) as split4
  from dual

結果:

a,1,b,2,ccdd;ef;    a1b2ccdd;ef;    a1b2ccddef    a1b2ef

 

數據結構——字符數組

CREATE OR REPLACE TYPE chrs_tbl IS TABLE of VARCHAR2(100)
/

該字符數組用於保存分割后的字符。根據這個定義,如果分割單個字符,那沒什么限制;但是如果按你指定的分隔符來分割,那就有限制了。限制是分割后的單個字符不能超過 100 個。其實,這樣的限制也沒什么關系,為自己系統定制一個分割函數就可以。

字符串分割函數 PL/SQL 包

包規范定義
create or replace package strutil is
 
  -- Author  : ADMINISTRATOR
  -- Created : 2012/11/10 17:15:14
  -- Purpose : 字符串分割
 
  -- 
  v_desc_chrs_tbl chrs_tbl;
  -- 
  v_length NUMBER;
  v_step   NUMBER;
 
  FUNCTION splitstr(v_str IN VARCHAR2) RETURN chrs_tbl;
 
  FUNCTION splitstrbyseparators(v_str        in VARCHAR2,
                                v_separators in VARCHAR2) RETURN chrs_tbl;
 
  FUNCTION concat(chrs in chrs_tbl) RETURN VARCHAR2;
 
  PROCEDURE output(chrs in chrs_tbl);
 
end strutil;
包體定義
  • splitstr 函數 - 按單個字符分割。利用 substr 函數,起始位置在變化(該函數第二個參數),而“步長”(該函數第三個參數)永遠為 1。
  • splitstrbyseparators - 按指定的字符串分割。原理同 splitstr 函數一樣。利用 regexp_instr 函數匹配,將分隔符變成正則表達式,到原串匹配,以確定截取子字符串的起始位置和步長。若原串中沒有指定的分割符,則按原串,否則分割。
  • concat - 將分割的字符串數組連接成字符串。
  • output - 輸出分割的字符串數組。
create or replace package body strutil is
  /* 單個字符串 
      v_str : 任意字符串
   */
  FUNCTION splitstr(v_str in VARCHAR2) RETURN chrs_tbl IS
    i NUMBER;
  BEGIN
    v_desc_chrs_tbl := chrs_tbl();
    i               := 1;
    v_length        := LENGTH(v_str);
    v_step          := 1;
    WHILE i <= v_length LOOP
      v_desc_chrs_tbl.extend;
      v_desc_chrs_tbl(v_desc_chrs_tbl.count) := substr(v_str, i, 1);
      i := i + 1;
    END LOOP;
    RETURN v_desc_chrs_tbl;
  END splitstr;
 
  /* 按分割符分割字符串 
      v_str : 任意不超過 1000 個字符的字符串
      v_separators : 分割符,如 ',' ',;' ',;|'
   */
  FUNCTION splitstrbyseparators(v_str        in VARCHAR2,
                                v_separators in VARCHAR2) RETURN chrs_tbl IS
    i NUMBER;
    j NUMBER;
  BEGIN
    v_desc_chrs_tbl := chrs_tbl();
  
    v_length := LENGTH(v_str);
    j        := 1;
    i        := REGEXP_INSTR(v_str, '[' || v_separators || ']', j);
    v_step   := i - j;
    IF i <= 0 THEN
      v_desc_chrs_tbl.extend;
      v_desc_chrs_tbl(v_desc_chrs_tbl.count) := v_str;
    ELSE
      WHILE i > 0 AND i <= v_length LOOP
        v_desc_chrs_tbl.extend;
        v_desc_chrs_tbl(v_desc_chrs_tbl.count) := SUBSTR(v_str, j, v_step);
        j := j + v_step + 1;
        i := REGEXP_INSTR(v_str, '[' || v_separators || ']', j);
        v_step := i - j;
      END LOOP;
      IF j <= v_length THEN
        v_desc_chrs_tbl.extend;
        v_desc_chrs_tbl(v_desc_chrs_tbl.count) := SUBSTR(v_str, j);
      END IF;
    END IF;
    RETURN v_desc_chrs_tbl;
  END splitstrbyseparators;
 
  FUNCTION concat(chrs in chrs_tbl) RETURN VARCHAR2 IS
    v_str VARCHAR2(1000);
  BEGIN
    IF chrs.count > 0 THEN
      FOR i IN 1 .. chrs.count LOOP
        v_str := v_str || chrs(i);
      END LOOP;
    ELSE
      v_str := '';
    END IF;
    RETURN v_str;
  END;
 
  PROCEDURE output(chrs in chrs_tbl) IS
  BEGIN
    IF chrs.count > 0 THEN
      FOR i IN 1 .. chrs.count LOOP
        dbms_output.put_line(chrs(i));
      END LOOP;
      dbms_output.put_line('--success.');
    ELSE
      dbms_output.put_line('--failure.');
    END IF;
  END;
 
end strutil;

當自定義分隔符分割時,限制是分割后的字符不能超過 100 個,總體長度不能 1000 個。實際中,根據你系統的情況定制一個就行。個人覺得,沒必要寫通用的。

結果

字符串單個分割:

SQL> exec strutil.output(strutil.splitstr('a,1,b,2,ccdd;ef;'));
 
a
,
1
,
b
,
2
,
c
c
d
d
;
e
f
;
--success.
 
PL/SQL procedure successfully completed
 
SQL> 

分割符為 "," 的分割結果:

SQL> exec strutil.output(strutil.splitstrbyseparators('a,1,b,2,ccdd;ef;', ','));
 
a
1
b
2
ccdd;ef;
--success.
 
PL/SQL procedure successfully completed
 
SQL> 

分割符為 ",;" 的分割結果:

SQL> exec strutil.output(strutil.splitstrbyseparators('a,1,b,2,ccdd;ef;', ',;'));
 
a
1
b
2
ccdd
ef
--success.
 
PL/SQL procedure successfully completed
 
SQL> 

分割符為 ",;|\" 的分割結果:

SQL> exec strutil.output(strutil.splitstrbyseparators('a,1,b,2,;|\;ef;', ',;|\'));
 
a
1
b
2
 
 
 
 
ef
--success.
 
PL/SQL procedure successfully completed
 
SQL> 

下載 Demo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM