oracle, xmltype/clob substr 循环

Posted

技术标签:

【中文标题】oracle, xmltype/clob substr 循环【英文标题】:oracle, xmltype/clob substr loop 【发布时间】:2018-04-19 09:56:01 【问题描述】:

我有一个带有大型 xmltype 的 clob。 我的目标是将这个 xml 切割成更小的部分,因为我需要通过文件将大型 xml(超过 35000 个字符)传输到另一个系统中。 到目前为止我做了什么:

    create table test_clob(
    id number(3),
    val clob);

通过代码

    declare
      cl         clob;
      xm         xmltype;
      response   xmltype;
      l_length   pls_integer;
      l_loop_cnt pls_integer;
    begin

      select ltR_clob 
      into   cl
      from   table1
      WHERE  cal1= 50470071;

      l_length   := length(cl);
      l_loop_cnt := ceil(l_length / 1000);
      dbms_output.put_line( 'len: '||l_length|| ' loop_cnt: '||l_loop_cnt);
      for rec in 1 .. l_loop_cnt
      loop

       dbms_output.put_line('update test_clob set val = val || ''' ||
                          dbms_lob.substr(cl, 1 + ((rec-1) *1000) , rec * 1000)||''';');
                          dbms_output.new_line;
      end loop;


    end;
    /

它应该看起来像在文件/输出中

    update ... set val = val || part1xml;
    update ... set val = val || part2xml;

etc...

问题是此更新部分是随机顺序或部分重复 f.e.

update test_clob set val = val || 'attribute>
      <attribute>
        <name>val1</name>
        <value>0</value>
      </attribute>
    </attributes>...'

update test_clob set val = val || 'attribute>
      <attribute>
        <name>val1</name>
        <value>0</value>
      </attribute>
    </attributes>...'

或者错误的顺序:

       '...<source-ids>
                  <identifier>
                    <person-id>11111111111111111</person-id>
              ';

        update test_clob set val = val || 'erson-id>0123545543334</person-id>
                    <source-system>THREER</source-system>
                  </identifier>'

有什么想法吗?我不知道为什么会这样。或者也许有人有另一个想法,你如何将 large throw large xml 放入文件中,以便在另一个数据库中插入它不会有问题?

【问题讨论】:

【参考方案1】:

您对dbms_lob.substr() 的论点是错误的。首先,您可能有错误的偏移量和数量 - 由于某种原因,它与普通的 substr() 相反。然后你使用rec*1000 作为数量,而实际上你只需要1000 - 否则每个块都会变长,这不是你想要的,并且会继续重叠。

所以:

    dbms_output.put_line('update test_clob set val = val || ''' ||
                         dbms_lob.substr(cl, 1000, 1 + ((rec-1) * 1000)) ||''';');

根据您使用的工具,可能有内置工具可以执行此操作; SQL Developer 和 SQLcl 可以生成插入语句,将 CLOB 拆分为可管理的块,例如:

select /*insert*/ id, val from test_clob;

set sqlformat insert;
select id, val from test_clob;

Read more about that client functionality。其他客户端可能也有类似的技巧。

【讨论】:

以上是关于oracle, xmltype/clob substr 循环的主要内容,如果未能解决你的问题,请参考以下文章

oracle拼接子查询返回的多个结果

在oracle存储过程中将数据插入到多个表中

Oracle In(匹配)子句

Oracle In(匹配)子句

关于Oracle job的笔记

关于Oracle job的笔记