oracle, xmltype/clob substr 循环
oracle, xmltype/clob substr loop
我有一个大 xml 类型的 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;
/
它应该看起来像 file/output
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 放入文件中,以便在另一个数据库中插入它不会有问题?
出于某种原因,您对 dbms_lob.substr()
are wrong. Firstly you probably have the offset and amount the wrong way round - it's the reverse of plain substr()
的论点。然后你使用 rec*1000
作为数量,而实际上你只想要 1000
- 否则每个块都会变长,这不是你想要的,并且会继续重叠。
所以:
dbms_output.put_line('update test_clob set val = val || ''' ||
dbms_lob.substr(cl, 1000, 1 + ((rec-1) * 1000)) ||''';');
根据您使用的工具,可能有内置工具可以执行此操作; SQL 开发人员和 SQLcl 可以生成将 CLOB 拆分为可管理块的插入语句,例如:
select /*insert*/ id, val from test_clob;
或
set sqlformat insert;
select id, val from test_clob;
Read more about that client functionality。其他客户可能也有类似的技巧。
我有一个大 xml 类型的 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;
/
它应该看起来像 file/output
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 放入文件中,以便在另一个数据库中插入它不会有问题?
出于某种原因,您对 dbms_lob.substr()
are wrong. Firstly you probably have the offset and amount the wrong way round - it's the reverse of plain substr()
的论点。然后你使用 rec*1000
作为数量,而实际上你只想要 1000
- 否则每个块都会变长,这不是你想要的,并且会继续重叠。
所以:
dbms_output.put_line('update test_clob set val = val || ''' ||
dbms_lob.substr(cl, 1000, 1 + ((rec-1) * 1000)) ||''';');
根据您使用的工具,可能有内置工具可以执行此操作; SQL 开发人员和 SQLcl 可以生成将 CLOB 拆分为可管理块的插入语句,例如:
select /*insert*/ id, val from test_clob;
或
set sqlformat insert;
select id, val from test_clob;
Read more about that client functionality。其他客户可能也有类似的技巧。