Oracle 字符串切割/转列

  第一种方式, 简单点:

-- 字符串转列 (:str 为待切串)
SELECT (REGEXP_SUBSTR(:str, '[^,]+', 1, ROWNUM) ) split
  FROM DUAL
CONNECT BY ROWNUM <= (LENGTH(:str) - LENGTH(REGEXP_REPLACE(:str, ',', '')) + 1)
;
-- 或者
WITH TEST AS (
    select :str as str from dual
)
 SELECT REGEXP_SUBSTR(STR, '[^,]+', 1, rownum) split
 FROM TEST
 CONNECT BY rownum <= LENGTH(STR) - LENGTH(REGEXP_REPLACE(STR, ',', '')) + 1
 ;

这里提供测试sql, 大家可以自己试一试执行速度:

-- 随机数
WITH TEST AS (
    SELECT  listagg(tt.aa, ',') within group ( order by tt.aa) str FROM (
      select abs(DBMS_RANDOM.RANDOM) aa, rownum rn 
      from dual connect by ROWNUM<=150
        ) tt
)
 SELECT STR, to_number(REGEXP_SUBSTR(STR, '[^,]+', 1, rownum)) num
 FROM TEST
 CONNECT BY rownum<=LENGTH(STR)-LENGTH(REGEXP_REPLACE(STR,',',''))+1
 ;
 
-- 自然数
WITH TEST AS (
    SELECT  listagg(tt.rn, ',') within group ( order by tt.rn) str FROM (
    select rownum rn from dual connect by ROWNUM<=200
        ) tt
)
 SELECT STR, to_number(REGEXP_SUBSTR(STR, '[^,]+', 1, rownum)) num
 FROM TEST
 CONNECT BY rownum<=LENGTH(STR)-LENGTH(REGEXP_REPLACE(STR,',',''))+1
 ;

  第二种方式:

-- 1. 创建type
CREATE OR REPLACE TYPE ty_str_split IS TABLE OF VARCHAR2 (4000);
-- 2. 创建函数
create or replace FUNCTION fn_split(
    p_str       IN VARCHAR2,
    p_delimiter IN VARCHAR2)
  RETURN ty_str_split PIPELINED
IS
  j    INT := 0;
  i    INT := 1;
  LEN  INT := 0;
  len1 INT := 0;
  str  VARCHAR2 (4000);
BEGIN
  LEN    := LENGTH (p_str);
  len1   := LENGTH (p_delimiter);
  WHILE j < LEN
  LOOP
    j     := INSTR (p_str, p_delimiter, i);
    IF j   = 0 THEN
      j   := LEN;
      str := SUBSTR (p_str, i);
      PIPE ROW (str);
      IF i >= LEN THEN
        EXIT;
      END IF;
    ELSE
      str := SUBSTR (p_str, i, j - i);
      i   := j                   + len1;
      PIPE ROW (str);
    END IF;
  END LOOP;
  -- PIPE ROW 语句用来返回该集合的单个元素,该函数必须以一个空的 RETURN 语句结束
  RETURN;
END fn_split;

测试:

-- 使用 TABLE 操作符进行测试
SELECT * FROM TABLE (fn_split (
(SELECT  listagg(tt.rn, ',') within group ( order by tt.rn) str FROM (
    SELECT ROWNUM rn FROM dual CONNECT BY ROWNUM<=1000
        ) tt)
, ','))
;

附测试图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
The end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值