Oracle
 sql >> база данни >  >> RDS >> Oracle

Нежелани нови редове при спулиране на sqlplus резултат в xml файл

Както предложи @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 писане на сървъра вместо спулинг на клиента.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Изтриване на таблица в Oracle SQL

  2. Показване на всички екземпляри, които трябва да бъдат динамично регистрирани със слушател

  3. Обединяване на припокриващи се сегменти за измерване на ефективната дължина

  4. jetty и Oracle Connection Pooling

  5. Oracle JDBC тънък драйвер SSL