Както предложи @kfinity, това е свързано с обработката на CLOB, но също и с това как dbms_output
върши работа. Вие четете CLOB на части от 32k и записвате всяка от тези части с put_line()
, който добавя знак за нов ред след всяка част от 32k. Те не са подравнени с никакви съществуващи прекъсвания на редове във вашия XML документ, така че получавате оригиналните прекъсвания, след това допълнителни - които изглеждат някак произволни и по средата на текста, но всъщност са на предвидими места.
Очевидно решение е да преминете от put_line()
към put()
, но това ще наруши максималния размер на буфера и ще изведе нещо като „ORU-10028:препълване на дължината на реда, ограничение от 32767 байта на ред“.
Вместо да четете на фиксирани 32k парчета, можете да четете един ред наведнъж; CLOB всъщност не разбира редовете като такива, но можете да търсите прекъсвания на редове, нещо като:
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;
if
търси знак за нов ред след текущата позиция. Ако намери такъв, сумата се изчислява като броя знаци от текущата позиция до този нов ред (или по-скоро минус един - тъй като не искате самия нов ред), той чете толкова много знаци и след това коригира позицията по прочетената сума плюс едно (за да пропуснете новия ред - което не искате/нуждаете като put_line()
добавя един все още).
Ако не намери такъв, той чете до 32k - надяваме се само веднъж; ако има повече от това може да са останали символи без прекъсване на ред, тогава ще направи второ четене, но все пак ще добави онзи измамен допълнителен нов ред и ще прекъсне този ред. Не можете да направите много за това, като използвате dbms_output
все пак ще трябва да превключите към utl_file
писане на сървъра вместо спулинг на клиента.