2010-07-14 9 views
1

J'ai une procédure qui utilise une table temporaire. Je veux me débarrasser de la table temporaire et utiliser une collection pour supprimer les E/S. il a environ 5000 enregistrements.comment convertir la table temporaire globale en collection/type dans la procédure oracle

Je veux insérer des données dans cette collection, alors je veux accéder à la collection comme:

select * from table(my_type_for_gtt)

Je ne pouvais pas trouver un exemple. Je suis confus, dois-je d'abord créer un type d'enregistrement et ensuite créer comme table de?

quelqu'un peut s'il vous plaît montrer un petit exemple rapide?

+0

double possible de [façons d'éviter des tables temporaires globales dans l'oracle] (http://stackoverflow.com/questions/2918466/ways-to-avoid-global-temp-tables-in-oracle) – APC

+0

Vérifier sur ma réponse à cette question précédente: http://stackoverflow.com/questions/2918466/ways-to-avoid-global-temp-tables-in-oracle/2918935#2918935 – APC

+0

J'ai jeté un exemple de collection rapide ci-dessous, bien qu'il duplique votre réponse plus détaillée. Espérons que le PO puisse fermer cette question. – JulesLt

Répondre

2

Vous êtes dans la bonne direction - d'abord créer vos types

CREATE TYPE myEntry 
AS 
OBJECT 
    (attr1 NUMBER, 
    attr2 VARCHAR2(20) 
); 

CREATE TYPE myCollection AS TABLE OF myEntry; 

Suivant certaines fonctions par exemple de retour 'lignes' de votre collection

CREATE OR REPLACE FUNCTION ExampleMyCollection1 
RETURN myCollection 
IS 
    lCol myCollection := myCollection(); /* Must initialise empty collection */ 
BEGIN 
    lCol.EXTEND(1000); 
    /* Populate the collection entries with objects */ 
    FOR i IN 1..1000 LOOP 
     lCol(i) := myEntry(i,'An entry for '||i); 
    END LOOP; 
    RETURN lCol; 
END ExampleMyCollection1; 

SELECT * FROM TABLE(ExampleMyCollection1); 

Variation - cette fois-ci, nous utilisons pipelining, donc que les résultats sont renvoyés à la requête à mesure qu'ils sont créés. Notez qu'en dépit d'être une fonction, il n'y a pas de fin RETURN pour une fonction PIPELINED.

CREATE OR REPLACE FUNCTION ExampleMyCollection2 
RETURN myCollection PIPELINED 
IS 
BEGIN 
    FOR i IN 1..1000 LOOP 
     PIPE ROW(myEntry(i,'An entry for '||i)); 
    END LOOP; 
END ExampleMyCollection2; 

SELECT * FROM TABLE(ExampleMyCollection2); 

Pour remplacer votre table temporaire avec des données purement en mémoire, vous besoin de quelque chose pour stocker votre collection - à savoir un paquet avec l'état.

CREATE OR REPLACE PACKAGE pMyCollection 
AS 
    PROCEDURE AddEntry(entry IN myEntry); 

    FUNCTION fCurrentCollection RETURN myCollection; 

    PROCEDURE ClearEntries; 

END pMyCollection; 

CREATE OR REPLACE PACKAGE BODY pMyCollection 
AS 
    /* Stateful variable to hold the collection */ 
    pCollection myCollection := myCollection(); 

    PROCEDURE AddEntry(entry IN myEntry) 
    IS 
    BEGIN 
     pCollection.EXTEND; 
     pCollection(pCollection.LAST) := entry; 
    END; 

    PROCEDURE ClearEntries 
    IS 
    BEGIN 
     pCollection.DELETE; 
    END ClearEntries; 

    FUNCTION fCurrentCollection 
    RETURN myCollection 
    IS 
    BEGIN 
     /* Return whole collection - we could use pipelining and parameters to return partial elements */ 
     RETURN pCollection; 
    END fCurrentCollection; 

END pMyCollection; 
Questions connexes