sql >> Database >  >> RDS >> Oracle

XML PLSQL Iteratief genereren

Het heeft geen zin om te proberen zeer grote XML in PL/SQL te genereren. Het probleem is niet PL/SQL als zodanig, maar dat PL/SQL alleen XML DOM ondersteunt, en DOM kan grote XML helemaal niet goed aan. U zegt niet hoe groot het XML-document is, maar het zou me niet verbazen als het geheugen dat door PL/SQL wordt gebruikt om uw document op te bouwen, ongeveer 10 tot 30 keer zo groot is als het resulterende document.

Is er een optie om de XML te genereren met iets anders dan PL/SQL? Zo niet, en ik moest echt grote XML-bestanden genereren in een Oracle-database, dan zou ik overwegen om Java-opgeslagen procedures te gebruiken. Deze vraag heeft enkele antwoorden over hoe je dit soort dingen in Java kunt doen.

BEWERKEN als reactie op je opmerking:je code schrijft zeker niet regel voor regel. Het schrijft het lot samen, een feit dat ik heb geverifieerd door het uit te voeren met behulp van de query SELECT * FROM all_objects op mijn Oracle 11g XE-database. De lus liep één keer en schreef 7341 objecten, waardoor een XML-bestand ontstond dat iets meer dan 3 MB groot was.

Ik heb vervolgens geprobeerd uw code aan te passen om de 'incrementele' benadering die u beschrijft beter te ondersteunen. Dit betrof:

  • een regel toevoegen dbms_xmlgen.setmaxrows(ctx, max_rows); om DBMS_XMLGEN te vertellen om slechts 5 rijen tegelijk te genereren. Anders probeert het de kavel in één keer te genereren.

  • het wijzigen van de code bovenaan de WHILE loop naar

    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
    
  • het toevoegen van de eerste van deze drie regels net voor de onderkant van de WHILE lus.

Ik heb vervolgens uw code opnieuw uitgevoerd en ik kon zien dat elke batch van vijf rijen elke keer naar het bestand werd geschreven. Er is echter een klein probleem met deze aanpak, in die zin dat het bestand elke keer werd overschreven. Uiteindelijk had ik maar één record in het XML-uitvoerbestand. Ik kan me niet voorstellen dat dit is wat je wilt.

De WRITETOCLOB , WRITETOBUFFER en WRITETOFILE methoden in DBMS_XMLDOM hint niet naar de mogelijkheid om aan een bestaand bestand toe te voegen, en om eerlijk te zijn verbaast het me niet dat ze dat niet doen. Als je dat zou kunnen, zou je eindigen met ongeldige XML, omdat er meer dan één <?xml ... ?> zou zijn aangifte in het bestand.

Ik blijf bij mijn eerdere advies. Gebruik SAX of StAX wanneer u te maken heeft met grote XML, in een Oracle-database of elders. PL/SQL ondersteunt ook niet, dus doe wat je moet doen in Java-opgeslagen procedures of doe het uit de database.




  1. database:primaire sleutel, geclusterd of niet-geclusterd

  2. Query uitvoeren met een instructie in een VARCHAR2-kolom

  3. Hoe waarde terug te geven van een belofte

  4. Help me met deze MySql full outer join (of unie)