2011-09-27 17 views
12

Desidero scrivere una funzione Oracle che raccolga alcuni dati in più passaggi in una variabile di raccolta e utilizzi i dati di raccolta all'interno di una query SELECT come in questo esempio molto semplificato:Come utilizzare una raccolta all'interno di un'istruzione Oracle Oracle

CREATE OR REPLACE FUNCTION TESTFUNC01 RETURN VARCHAR2 AS 
    -- INT_LIST is declared globally as "TYPE INT_LIST IS TABLE OF INTEGER" 
    MyList INT_LIST := INT_LIST(); 
    MyName VARCHAR2(512); 
BEGIN 
    MyList.Extend(3); 
    MyList(0) := 1; 
    MyList(1) := 2; 
    MyList(2) := 3; 

    SELECT Name INTO MyName 
    FROM Item WHERE ItemId NOT IN MyList; 
    RETURN MyName; 
END TESTFUNC01; 

Sfortunatamente la parte "NOT IN MyList" non è un SQL valido. C'è un modo per ottenere questo?

risposta

15

Quello che stai cercando è la funzione table:

CREATE OR REPLACE FUNCTION TESTFUNC01 RETURN VARCHAR2 AS 
    -- INT_LIST is declared globally as "TYPE INT_LIST IS TABLE OF INTEGER" 
    MyList INT_LIST := INT_LIST(); 
    MyName VARCHAR2(512); 
BEGIN 
    MyList.Extend(3); 
    MyList(1) := 1; 
    MyList(2) := 2; 
    MyList(3) := 3; 

    SELECT Name INTO MyName 
    FROM Item WHERE ItemId NOT IN (select * from table(MyList)); 
    RETURN MyName; 
END TESTFUNC01; 
+4

Grazie per l'aiuto rapido. Mi sono perso nella lettura della documentazione Oracle ... – blerontin

+0

Questo è quello che stavo cercando. Grazie mille. – Sid

5

si può fare in questo modo:

CREATE OR REPLACE FUNCTION TESTFUNC01 RETURN VARCHAR2 AS 
    -- INT_LIST is declared globally as "TYPE INT_LIST IS TABLE OF INTEGER" 
    MyList INT_LIST := INT_LIST(); 
    MyName VARCHAR2(512); 
BEGIN 
    MyList.Extend(3); 
    MyList(1) := 1; 
    MyList(2) := 2; 
    MyList(3) := 3; 

    SELECT Name INTO MyName 
    FROM Item WHERE ItemId NOT IN (SELECT COLUMN_VALUE FROM TABLE(MyList)); 
    RETURN MyName; 
END TESTFUNC01; 

Nota che ho cambiato anche gli indici della lista. L'inizio con 1 (non 0).

4

- INT_LIST viene dichiarata globalmente come "TIPO INT_LIST È TABELLA DI INTEGER"

Che assomiglia a una dichiarazione di PL/SQL. Le istruzioni SELECT utilizzano il motore SQL. Ciò significa che devi dichiarare il tuo TYPE in SQL.

CREATE TYPE INT_LIST AS TABLE OF NUMBER(38,0); 
/

Quindi è possibile utilizzare in un'istruzione SELECT:

SELECT Name INTO MyName 
FROM Item WHERE ItemId NOT IN (select * from table(MyList)); 

Naturalmente, è necessario assicurarsi che la vostra query restituisce solo una riga, o che il programma gestisce il TOO_MANY_ROWS eccezione.

5

Se la vostra utilizzando Oracle 10 è possibile utilizzare le estensioni collezioni:

CREATE OR REPLACE FUNCTION TESTFUNC01 RETURN VARCHAR2 AS 
    -- INT_LIST is declared globally as "TYPE INT_LIST IS TABLE OF INTEGER" 
    MyList INT_LIST := INT_LIST(); 
    MyName VARCHAR2(512); 
BEGIN 
    MyList.Extend(3); 
    MyList(1) := 1; 
    MyList(2) := 2; 
    MyList(3) := 3; 

    SELECT Name INTO MyName 
    FROM Item WHERE ItemId MEMBER OF MyList; 
    RETURN MyName; 
END TESTFUNC01; 

per maggiori dettagli si veda this post