Nie ma sensu próbować generować bardzo dużego XML w PL/SQL. Problemem nie jest PL/SQL jako taki, ale to, że PL/SQL obsługuje tylko XML DOM, a DOM w ogóle nie radzi sobie dobrze z dużymi XML. Nie mówisz, jaki masz rozmiar dokumentu XML, ale nie zdziwiłbym się, gdybym stwierdził, że pamięć używana przez PL/SQL do zbudowania twojego dokumentu jest około 10 do 30 razy większa od rozmiaru dokumentu wynikowego.
Czy istnieje możliwość wygenerowania XML przy użyciu czegoś innego niż PL/SQL? Jeśli nie, a naprawdę musiałbym generować duże pliki XML w bazie danych Oracle, rozważyłbym użycie procedur składowanych Java. To pytanie ma kilka odpowiedzi na to, jak robić tego typu rzeczy w Javie.
EDYTUJ w odpowiedzi na twój komentarz:twój kod na pewno nie pisze jednej linii na raz. Zapisuje wiele razem, fakt, który zweryfikowałem uruchamiając go za pomocą zapytania SELECT * FROM all_objects
na mojej bazie danych Oracle 11g XE. Pętla uruchomiła się raz i zapisała 7341 obiektów, tworząc plik XML o rozmiarze nieco ponad 3 MB.
Następnie spróbowałem zmodyfikować Twój kod, aby lepiej obsługiwać opisane przez Ciebie podejście „przyrostowe”. Wiązało się to z:
-
dodanie linii
dbms_xmlgen.setmaxrows(ctx, max_rows);
aby powiedzieć DBMS_XMLGEN, aby generował tylko 5 wierszy na raz. W przeciwnym razie próbuje wygenerować partię za jednym razem. -
modyfikowanie kodu na górze
WHILE
pętla doxml_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
-
dodanie pierwszej z tych trzech linii tuż przed dolną częścią
WHILE
pętla.
Następnie ponownie uruchomiłem twój kod i mogłem zobaczyć, jak za każdym razem zapisuje każdą partię pięciu wierszy do pliku. Jest jednak pewien problem z tym podejściem, ponieważ plik był nadpisywany za każdym razem. Na koniec miałem tylko jeden rekord w wyjściowym pliku XML. Nie wyobrażam sobie, żeby to było to, czego chcesz.
WRITETOCLOB
, WRITETOBUFFER
i WRITETOFILE
metody w DBMS_XMLDOM
nie sugeruj możliwości dołączania do istniejącego pliku i szczerze mówiąc nie dziwię się, że tak nie jest. Gdybyś mógł, skończyłbyś z nieprawidłowym kodem XML, ponieważ byłoby więcej niż jeden <?xml ... ?>
deklaracja w pliku.
Podtrzymuję moją poprzednią radę. Zawsze, gdy musisz mieć do czynienia z dużym XML, w bazie danych Oracle lub gdzie indziej, użyj SAX lub StAX. PL/SQL również nie obsługuje, więc rób wszystko, co musisz zrobić w procedurach składowanych Java lub rób to poza bazą danych.