Es hat keinen Sinn, sehr große XML-Daten in PL/SQL zu generieren. Das Problem ist nicht PL/SQL als solches, sondern dass PL/SQL nur XML DOM unterstützt und DOM große XML überhaupt nicht gut handhabt. Sie sagen nicht, wie groß Ihr XML-Dokument ist, aber es würde mich nicht überraschen, wenn der von PL/SQL zum Erstellen Ihres Dokuments verwendete Speicher etwa das 10- bis 30-fache der Größe des resultierenden Dokuments beträgt.
Gibt es eine Möglichkeit, das XML mit etwas anderem als PL/SQL zu generieren? Wenn nicht, und ich wirklich große XML-Dateien in einer Oracle-Datenbank generieren musste, würde ich die Verwendung von gespeicherten Java-Prozeduren in Betracht ziehen. Diese Frage hat einige Antworten darauf, wie man so etwas in Java macht.
BEARBEITEN als Antwort auf Ihren Kommentar:Ihr Code schreibt definitiv nicht eine Zeile nach der anderen. Es schreibt das Los zusammen, eine Tatsache, die ich überprüft habe, indem ich es mit der Abfrage SELECT * FROM all_objects
ausgeführt habe auf meiner Oracle 11g XE-Datenbank. Die Schleife lief einmal und schrieb 7341 Objekte, wodurch eine etwas mehr als 3 MB große XML-Datei erstellt wurde.
Ich habe dann versucht, Ihren Code zu ändern, um den von Ihnen beschriebenen "inkrementellen" Ansatz besser zu unterstützen. Dies beinhaltete:
-
Hinzufügen einer Zeile
dbms_xmlgen.setmaxrows(ctx, max_rows);
um DBMS_XMLGEN anzuweisen, nur 5 Zeilen gleichzeitig zu generieren. Andernfalls wird versucht, das Los auf einmal zu generieren. -
Ändern des Codes am Anfang von
WHILE
Schleife zuxml_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
-
Hinzufügen der ersten dieser drei Zeilen direkt vor dem Ende von
WHILE
Schleife.
Ich habe dann Ihren Code erneut ausgeführt und konnte sehen, dass er jedes Mal jeden Stapel von fünf Zeilen in die Datei schreibt. Bei diesem Ansatz gibt es jedoch ein kleines Problem, da die Datei jedes Mal überschrieben wurde. Am Ende hatte ich nur einen einzigen Datensatz in der ausgegebenen XML-Datei. Ich kann mir nicht vorstellen, dass das das ist, was Sie wollen.
Der WRITETOCLOB
, WRITETOBUFFER
und WRITETOFILE
Methoden in DBMS_XMLDOM
weisen Sie nicht auf die Möglichkeit hin, an eine vorhandene Datei anzuhängen, und um ehrlich zu sein, bin ich nicht überrascht, dass dies nicht der Fall ist. Wenn Sie könnten, würden Sie mit ungültigem XML enden, da es mehr als einen <?xml ... ?>
geben würde Deklaration in der Datei.
Ich bleibe bei meinem bisherigen Rat. Wann immer Sie mit großem XML umgehen müssen, in einer Oracle-Datenbank oder anderswo, verwenden Sie SAX oder StAX. PL/SQL wird auch nicht unterstützt, also machen Sie alles, was Sie tun müssen, in gespeicherten Java-Prozeduren oder aus der Datenbank heraus.