2017-10-11 4 views
0

J'ai une instruction select qui retourne 0 ou plusieurs lignes. J'essaye de trouver un proc de plsql avec un curseur pour produire la production de xml pour, toutes les rangées retournées dans 100 rangées à la fois. Je fais ceci pour morceler des rangées de loo à la fois basé sur l'exigence.Oracle plsql segmentant les lignes

Donc, fondamentalement, mon programme devrait suivre la logique ci-dessous

cursor c1 is select id,code_id,code_desc from table order by id; --returns some rows 

if c1%notfound 
    then return;` -- exit from procedure 
else 
loop 
    grab first 100 rows from select and append to a variable 
    and assign it to a variable; 
    update this variable into a clob field in a table. 
    grab next 100 rows and append into a variable 
    update this variable into a clob field in a table in another row;see below 
    table data 

    and so on 
    and grab remaining rows and append into a variable 
    print the variable; 
until no data found; 
exit 

Je suis en train de faire convertir la sortie de l'instruction select en texte XML.

La sortie devrait ressembler à quelque chose comme ci-dessous:

TABLE: STG_XML_DATA

LOOP_NO(NUMBER), XML_TEXT(CLOB), ROWS_PROCESSED 
1    <XML><id>1</ID><id>2</ID>..<ID>100</ID></XML>  100 
2    <XML><id>101</ID><id>102</ID>..<ID>200</ID></XML> 200 
3    <XML><id>301</ID><id>102</ID>..<ID>320</ID></XML> 20 

Quelqu'un peut-il aider s'il vous plaît

+0

Pourquoi vous essayez de traiter seulement 100 lignes à la fois? Et pourriez-vous préciser à quoi ressemblent vos lignes, ou à quoi ressemble "ajouter à une variable"? Vous pouvez par exemple stocker des lignes dans des collections PL/SQL, mais cela ne les rend pas vraiment plus faciles à imprimer. – kfinity

+0

J'essaye juste de découper les rangées 100 à la fois et d'ajouter cela dans la variable qui peut être stockée dans une table pas nécessairement imprimée. Je travaille sur la génération de texte xml qui suit un modèle. les valeurs renvoyées à partir de cette instruction select seront utilisées pour ajouter cela dans une colonne clob. – user1751356

+0

Avoir une lecture ici pour quelques informations très utiles sur le travail avec les curseurs, en particulier la limitation des lignes récupérées que vous voulez faire et comment savoir correctement quand vous avez atteint la fin (pas en utilisant NOTFOUND!): Http: // www. oracle.com/technetwork/issue-archive/2008/08-mar/o28plsql-095155.html –

Répondre

0

tout d'abord, pouvez-vous faire avec un seul INSERT ... SELECT déclaration qui fait ce que vous voulez avec une performance raisonnable? Si vous faites un million de lignes, oui, les diviser en morceaux peut être une bonne idée. Mais si c'est 100, cela pourrait être votre meilleur pari. Pour votre question actuelle, vous souhaitez utiliser BULK COLLECT dans une variable de collection et éventuellement FORALL. Donc, votre fonction va ressembler à quelque chose comme ceci:

DECLARE 
    TYPE id_tt IS TABLE OF NUMBER; 
    TYPE desc_tt IS TABLE OF VARCHAR2(100); 
    l_ids   id_tt; 
    l_code_ids id_tt; 
    l_code_descs desc_tt; 
    cursor c1 is select id,code_id,code_desc from table 
BEGIN 
    OPEN c1; 
    LOOP 
     FETCH c1 BULK COLLECT INTO l_ids, l_code_ids, l_code_descs 
     LIMIT 100; 

     EXIT WHEN l_ids.COUNT = 0; 

     FORALL idx IN 1..l_ids.COUNT 
     INSERT [... some insert statement here ...] 

     [... maybe some other processing here...] 
    END LOOP; 
    CLOSE c1; 
END; 

Ce que vous ne voulez absolument pas faire est d'extraire une ligne, la traiter, une autre ligne chercher, etc. SQL est un langage orienté jeu, alors essayez pour fonctionner sur des ensembles. Chaque fois que vous passez d'un contexte SQL à PL/SQL, il y a un coût et cela peut tuer votre performance.

Voir: http://www.oracle.com/technetwork/issue-archive/2012/12-sep/o52plsql-1709862.html

+0

Salut Eaolson, Merci beaucoup pour votre aide. Je suis actuellement coincé dans la compréhension de la façon de traiter le prochain ensemble de lignes dans le curseur. disons que si le curseur ne renvoie aucune ligne, alors le programme devrait quitter avec élégance, mais si le curseur a 220 lignes, alors en fonction de votre programme, les 100 premières lignes seront traitées dans une boucle forall. Que diriez-vous du prochain ensemble de rangées? Je comprends fort bien cela. S'il vous plaît aider! – user1751356

+0

C'est dans une structure LOOP ... END LOOP, non? Cela se répétera jusqu'à ce que la clause EXIT soit vraie, en traitant 100 lignes à chaque fois. – eaolson