Oracle
 sql >> Base de données >  >> RDS >> Oracle

Génération XML PLSQL itératif

Il ne sert à rien d'essayer de générer un XML très volumineux en PL/SQL. Le problème n'est pas PL/SQL en tant que tel, mais que PL/SQL ne prend en charge que XML DOM, et DOM ne gère pas du tout bien le grand XML. Vous ne dites pas quelle taille de document XML vous avez, mais je ne serais pas surpris de constater que la mémoire utilisée par PL/SQL pour construire votre document est d'environ 10 à 30 fois la taille du document résultant.

Existe-t-il une option pour générer le XML en utilisant autre chose que PL/SQL ? Sinon, et je devais vraiment générer de gros fichiers XML dans une base de données Oracle, j'envisagerais d'utiliser des procédures stockées Java. Cette question a quelques réponses sur la façon de faire ce genre de chose en Java.

MODIFIER en réponse à votre commentaire :votre code n'écrit certainement pas une ligne à la fois. Il écrit le lot ensemble, un fait que j'ai vérifié en l'exécutant à l'aide de la requête SELECT * FROM all_objects sur ma base de données Oracle 11g XE. La boucle s'est exécutée une fois et a écrit 7341 objets, créant un fichier XML d'une taille d'un peu plus de 3 Mo.

J'ai ensuite essayé de modifier votre code pour mieux prendre en charge l'approche "incrémentale" que vous décrivez. Cela impliquait :

  • ajout d'une ligne dbms_xmlgen.setmaxrows(ctx, max_rows); pour indiquer à DBMS_XMLGEN de ne générer que 5 lignes à la fois. Sinon, il tente de générer le lot en une seule fois.

  • modifier le code en haut du WHILE boucle vers

    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
    
  • en ajoutant la première de ces trois lignes juste avant le bas du WHILE boucle.

J'ai ensuite réexécuté votre code, et je pouvais le voir écrire chaque lot de cinq lignes dans le fichier à chaque fois. Cependant, il y a un léger problème avec cette approche, en ce sens que le fichier a été écrasé à chaque fois. À la fin, je n'avais qu'un seul enregistrement dans le fichier XML de sortie. Je ne peux pas imaginer que ce serait ce que vous voulez.

Le WRITETOCLOB , WRITETOBUFFER et WRITETOFILE méthodes dans DBMS_XMLDOM ne faites pas allusion à la possibilité d'ajouter à un fichier existant, et pour être honnête, je ne suis pas surpris qu'ils ne le fassent pas. Si vous le pouviez, vous vous retrouveriez avec un XML invalide, car il y aurait plus d'un <?xml ... ?> déclaration dans le fichier.

Je maintiens mes conseils précédents. Chaque fois que vous avez besoin de traiter du XML volumineux, dans une base de données Oracle ou ailleurs, utilisez SAX ou StAX. PL/SQL ne prend pas en charge non plus, alors faites tout ce que vous devez faire dans les procédures stockées Java ou faites-le hors de la base de données.