用plsql逐行读取clob

2021-12-24 00:00:00 oracle plsql plsqldeveloper

在我的项目中,我使用 oracle 作为主数据库,但在解析 clob 时遇到了问题.所以假设我们有一个具有价值的clob

In my project i use oracle as primary database and i've faced a problem with parsing clob. So suppose we have a clob with value

   aaaaaa
   cccccc
   bbbbbb

它存储在表 test ...

And it's stored in table test ...

我需要编写 plsql 程序来获取这个 clob 并将其拆分,以便我将拥有包含三个项目的数组 [aaaaaa,cccccccc,bbbbbbb].

I need to write plsql procedure to get this clob and split it so that i will have array with three items [aaaaaa,cccccccc,bbbbbbb].

有没有可能的解决方案?

Is there any possible solutions?

推荐答案

这是一段有效的代码.出于性能目的,我建议您使用显式游标而不是隐式游标(FOR i IN (select...)).

Here is a piece of code that works. I suggest that you use explicit cursors instead of implicit ones (FOR i IN (select...)), for performance purpose.

首先是创建测试用例的脚本.

First here is the script to create testcase.

create table test (c clob);

insert into test (c) values (
'azertyuiop
qsdfghjklm
wxcvbn
');

然后这里是逐行读取 Clob 的脚本:

Then here is the script to read line by line Clob :

/* Formatted on 28/08/2012 14:16:52 (QP5 v5.115.810.9015) */
declare
    nStartIndex number := 1;
    nEndIndex number := 1;
    nLineIndex number := 0;
    vLine varchar2(2000);

    cursor c_clob is
    select c from test;

    c clob;
    -------------------------------
    procedure printout
       (p_clob in out nocopy clob) is
      offset number := 1;
      amount number := 32767;
      len    number := dbms_lob.getlength(p_clob);
      lc_buffer varchar2(32767);
      i pls_integer := 1;
    begin
      if ( dbms_lob.isopen(p_clob) != 1 ) then
        dbms_lob.open(p_clob, 0);
      end if;
      amount := instr(p_clob, chr(10), offset);
      while ( offset < len )
      loop
        dbms_lob.read(p_clob, amount, offset, lc_buffer);
        dbms_output.put_line('Line #'||i||':'||lc_buffer);
       offset := offset + amount;
       i := i + 1;
      end loop; 
          if ( dbms_lob.isopen(p_clob) = 1 ) then
        dbms_lob.close(p_clob);
      end if; 
    exception
      when others then
         dbms_output.put_line('Error : '||sqlerrm);
    end printout;
    ---------------------------
begin
    dbms_output.put_line('-----------');
    open c_clob;
    loop
       fetch c_clob into c;
       exit when c_clob%notfound;
       printout(c);
    end loop;
    close c_clob;
end;

'amount' 变量用于检测行尾位置.小心点,在某些情况下,行尾是 CHR(10)||CHR(13) (CR + LF),而在其他一些情况下,它只是 CHR(10).

'amount' variable is used to detect end of line position. Be carfull, in some case the end of line is CHR(10)||CHR(13) (CR + LF), and in some other cases it is only CHR(10).

相关文章