sql >> Databasteknik >  >> RDS >> Oracle

Genererar XML PLSQL Iterativ

Det är ingen idé att försöka generera mycket stor XML i PL/SQL. Problemet är inte PL/SQL som sådant, utan att PL/SQL bara stöder XML DOM, och DOM hanterar inte stor XML alls bra. Du säger inte vilken storlek på XML-dokument du har, men jag skulle inte bli förvånad över att finna att minnet som används av PL/SQL för att bygga ditt dokument är ungefär 10 till 30 gånger storleken på det resulterande dokumentet.

Finns det ett alternativ att generera XML med något annat än PL/SQL? Om inte, och jag var verkligen tvungen att generera stora XML-filer i en Oracle-databas, skulle jag överväga att använda lagrade Java-procedurer. Denna fråga har några svar på hur man gör sånt här i Java.

REDIGERA som svar på din kommentar:din kod skriver absolut inte en rad i taget. Det skriver partiet tillsammans, ett faktum som jag verifierade genom att köra det med frågan SELECT * FROM all_objects på min Oracle 11g XE-databas. Slingan körde en gång och skrev 7341 objekt, vilket skapade en XML-fil på drygt 3 MB.

Jag försökte sedan ändra din kod för att bättre stödja den "inkrementella" metoden du beskriver. Detta innebar:

  • lägga till en rad dbms_xmlgen.setmaxrows(ctx, max_rows); att berätta för DBMS_XMLGEN att endast generera 5 rader åt gången. Annars försöker den generera partiet på en gång.

  • ändra koden överst i WHILE loop till

    xml_result := dbms_xmlgen.getXML(ctx);
    num_rows_processed := DBMS_XMLGEN.GETNUMROWSPROCESSED(ctx);
    dbms_output.put_line('Got ' || num_rows_processed || ' rows processed');
    
    while num_rows_processed > 0
      -- rest of loop omitted
    
  • lägga till den första av dessa tre rader strax före botten av WHILE loop.

Jag körde sedan din kod igen och jag kunde se att den skrev varje sats på fem rader till filen varje gång. Det finns dock ett litet problem med detta tillvägagångssätt, eftersom filen skrevs över varje gång. I slutet hade jag bara en enda post i utdata-XML-filen. Jag kan inte föreställa mig att det här skulle vara vad du vill ha.

WRITETOCLOB , WRITETOBUFFER och WRITETOFILE metoder i DBMS_XMLDOM antyda inte möjligheten att lägga till en befintlig fil, och för att vara ärlig är jag inte förvånad över att de inte gör det. Om du kunde, skulle du sluta med ogiltig XML, eftersom det skulle finnas mer än en <?xml ... ?> deklaration i filen.

Jag står fast vid mina tidigare råd. Närhelst du behöver hantera stor XML, i en Oracle-databas eller någon annanstans, använd SAX eller StAX. PL/SQL stöder inte heller, så gör vad du än behöver göra i Java lagrade procedurer eller gör det från databasen.




  1. Sant/falskt vs 0/1 i MySQL

  2. Anpassad formatering av datum/tid i SQL Server

  3. Hur man timeout en mysql++-fråga i c++

  4. Hur ansluter jag mysql-databas och infogar data i den med Android-kod