Zoals @kfinity suggereerde, heeft dit te maken met CLOB-afhandeling, maar ook met hoe dbms_output
werken. Je leest de CLOB in blokken van 32k, en schrijft elk van die blokken weg met put_line()
, die een teken voor een nieuwe regel toevoegt na elke 32k chunk. Die zijn niet uitgelijnd met bestaande regeleinden in uw XML-document, dus u krijgt de originele onderbrekingen en daarna extra - die enigszins willekeurig lijken en midden in de tekst staan, maar zich in feite op voorspelbare plaatsen bevinden.
Een voor de hand liggende oplossing is om over te schakelen van put_line()
naar put()
, maar dat zal de maximale buffergrootte breken en zoiets als "ORU-10028:regellengteoverloop, limiet van 32767 bytes per regel".
In plaats van in vaste stukken van 32k te lezen, zou je regel voor regel kunnen lezen; de CLOB begrijpt lijnen als zodanig niet echt, maar je kunt zoeken naar regeleinden, zoiets als:
WHILE pos < v_clob_length LOOP
-- read to next newline if there is one, rest of CLOB if not
if dbms_lob.instr(v_clob, chr(10), pos) > 0 then
amount := dbms_lob.instr(v_clob, chr(10), pos) - pos;
dbms_lob.read(v_clob, amount, pos, buffer);
pos := pos + amount + 1; -- skip newline character
else
amount := 32767;
dbms_lob.read(v_clob, amount, pos, buffer);
pos := pos + amount;
end if;
dbms_output.put_line(buffer);
END LOOP;
De if
zoekt naar een teken voor een nieuwe regel, na de huidige positie. Als het er een vindt, wordt het aantal berekend als het aantal tekens van de huidige positie tot die nieuwe regel (of liever min één - omdat je de nieuwe regel zelf niet wilt), het leest zoveel tekens en past vervolgens de positie aan door het gelezen bedrag plus één (om de nieuwe regel over te slaan - die u niet wilt/nodig hebt als put_line()
voegt er nog een toe).
Als het er geen vindt, leest het tot 32k - hopelijk slechts één keer; als er meer dan dat aantal tekens over zijn zonder regeleinde, dan zal het een tweede keer lezen, maar toch die bedrieglijke extra nieuwe regel toevoegen en die regel breken. U kunt daar niet veel aan doen met dbms_output
u moet echter overschakelen naar utl_file
schrijven naar de server in plaats van naar de client te spoolen.