首页 > 解决方案 > 我们如何通过 PLSQL 逐行拆分 CLOB(有些行超过 32K 个字符)?

问题描述

我正在尝试拆分一个巨大的 CLOB,其中包含超过 32K 个字符的行。

我试着用这个

SELECT REGEXP_SUBSTR(file_cont, '[^'||chr(10)||']+', 1, LEVEL) AS substr
from data_tab where interface = 'Historical'
CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(file_cont, '[^'||chr(10)||']+')) + 1

data_tab包含一些以管道作为分隔符的文件。列file_cont是一个包含我们感兴趣的文件的 clob。但是,当我尝试执行上述查询时,它看起来像是一个无限循环。

有关信息,CLOB 包含 600 多行。

我想要做的是将 clob 逐行拆分为不同的 CLOB。你知道一个查询可以显示这个结果而不会陷入无限循环吗?

编辑:文件大小为 22MB。

先感谢您。

标签: oracleplsqlsplitclob

解决方案


我有一个用于拆分和 PCRE 正则表达式的特殊包: https ://github.com/xtender/XT_REGEXP

你可以在https://github.com/xtender/XT_REGEXP/blob/master/xt_regexp.pck找到这个函数

/**
 * Clob simple split
 */
  function clob_split_simple(p_clob in clob,p_delim in varchar2) 
  return clob_table pipelined is
    row clob;
    l_b number:=1;
    l_e number:=1;
    $IF DBMS_DB_VERSION.ver_le_11 $THEN
    $ELSE
    pragma UDF;
    $END
  begin
      while l_e>0
        loop
          l_e:=instr(p_clob,p_delim,l_b);
          pipe row(substr(p_clob,l_b,case when l_e>0 then l_e-l_b else length(p_clob)+length(p_delim)-l_b end));
          l_b:=l_e+length(p_delim);
        end loop;
  end clob_split_simple;

所以你可以使用这个流水线函数:

select * 
from table(xt_regexp.clob_split_simple(:clob,chr(10));

或者以这段代码为例。

clob_table 只是一个table of clob

https://github.com/xtender/XT_REGEXP/blob/master/types.sql

create or replace type clob_table as table of clob;
/
create or replace type date_table as table of date;
/
create or replace type number_table as table of number;
/
create or replace type varchar2_table as table of varchar2(4000);
/
create or replace type xml_table as table of xmltype;
/

更新:修复了长匹配的错误:返回 varchar2 的 dbms_lob.substr,替换为返回 clob 的 substr(clob)。


推荐阅读