2011-09-27 63 views
12

我想編寫一個Oracle函數,該函數將多個步驟中的某些數據收集到集合變量中,並在SELECT查詢中使用該集合數據,如下面這個非常簡單的示例:如何在Oracle SQL語句中使用集合

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; 

不幸的是,「NOT IN MyList」部分不是有效的SQL。有沒有辦法做到這一點?

回答

15

什麼你要找的是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

感謝您的快速幫助。我在瀏覽Oracle文檔時迷失了... – blerontin

+0

這就是我一直在尋找的東西。非常感謝。 – Sid

5

你可以這樣說:

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; 

請注意,我也改變了列表索引。從1開始(不是0)。

4

- INT_LIST宣佈在全球範圍爲 「類型INT_LIST是 整數表」

這看起來像一個PL/SQL聲明。 SELECT語句使用SQL引擎。這意味着你需要在SQL中聲明你的TYPE。

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

然後你就可以在SELECT語句中使用它:

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

當然,你需要確保你的查詢只返回一行,或者你的程序處理TOO_MANY_ROWS例外。

5

如果您使用的是Oracle 10,你可以使用集合擴展:

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; 

詳細內容見this post