sql >> Databáze >  >> RDS >> Oracle

Nechtěné nové řádky při zařazování výsledku sqlplus do souboru xml

Jak navrhl @kfinity, souvisí to se zpracováním CLOB, ale také se způsobem dbms_output funguje. Čtete CLOB v blocích po 32 kB a každý z těchto kousků zapisujete pomocí put_line() , který za každý 32k blok připojí znak nového řádku. Ty nejsou zarovnány s žádnými existujícími zalomeními řádků v dokumentu XML, takže získáte původní zalomení a pak další - které se objevují poněkud náhodně a uprostřed textu, ale ve skutečnosti jsou na předvídatelných místech.

Zřejmým řešením je přejít z put_line() na put() , ale to naruší maximální velikost vyrovnávací paměti a vyvolá něco jako "ORU-10028:přetečení délky řádku, limit 32767 bajtů na řádek".

Spíše než čtení v pevných 32k blocích, můžete číst jeden řádek najednou; CLOB ve skutečnosti nerozumí řádkům jako takovým, ale můžete hledat konce řádků, něco jako:

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 hledá znak nového řádku za aktuální pozicí. Pokud najde jeden, pak se množství vypočítá jako počet znaků od aktuální pozice k tomuto novému řádku (nebo spíše mínus jeden – protože samotný nový řádek nechcete), přečte tolik znaků a poté upraví pozici o přečtenou částku plus jedna (pro přeskočení nového řádku – což nechcete/nepotřebujete jako put_line() přidá ještě jednu).

Pokud žádný nenajde, přečte až 32k – doufejme, že pouze jednou; pokud zbývá více znaků bez zalomení řádku, provede se druhé čtení, ale stále přidá ten nepoctivý další nový řádek a zalomí tento řádek. Pomocí dbms_output s tím moc nenaděláte ale budete muset přepnout na utl_file zápisu na server namísto zařazování do klienta.




  1. Spark SQL a MySQL – SaveMode.Overwrite nevkládá upravená data

  2. Seskupit řádky Dodržení pořadí hodnot

  3. Nastavení přizpůsobené možnosti v uložené proceduře

  4. Příklady MINUTE() – MySQL