Reputation: 652
I have a clob with large xmltype. My goal is to cut this xml into smaller parts, because i need to transfer large xml (over 35000 chars) into another system through file. What i have done so far:
create table test_clob(
id number(3),
val clob);
and by code
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;
/
it supposed to look like in the file/output
update ... set val = val || part1xml;
update ... set val = val || part2xml;
etc...
problem is that this update parts are in random order or parts are repeated 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>...'
OR bad order:
'...<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>'
Any ideas? im losing my head why this is happening. Or mayby someone have another idea how tu put large throw large xml into file so that in another db there won't be a problem to insert it?
Upvotes: 0
Views: 556
Reputation: 191275
Your arguments to dbms_lob.substr()
are wrong. Firstly you probably have the offset and amount the wrong way round - it's the reverse of plain substr()
for some reason. And then you're using rec*1000
as the amount, when really you just want 1000
- otherwise each chunk gets longer, which isn't what you want, and would continue to overlap.
So:
dbms_output.put_line('update test_clob set val = val || ''' ||
dbms_lob.substr(cl, 1000, 1 + ((rec-1) * 1000)) ||''';');
Depending on the tools you are using, there may be built-in tools to do this; SQL Developer and SQLcl can generate insert statements that split CLOB up into manageable chunks, for instance, with:
select /*insert*/ id, val from test_clob;
or
set sqlformat insert;
select id, val from test_clob;
Read more about that client functionality. Other clients probably have similar tricks.
Upvotes: 1