2010-07-14 21 views
1

我有一个使用临时表的过程。我想摆脱临时表并使用集合来删除I/O。它有大约5000条记录。如何将全局临时表转换为Oracle过程中的集合/类型

我想将数据插入到这个集合,然后我要访问的集合,如:

select * from table(my_type_for_gtt)

我找不到这样的一个例子。我很困惑,我是否必须先创建一个记录类型,然后创建为表格?

有人可以展示一个小例子吗?

+0

的[如何避免Oracle全球临时表]可能重复(http://stackoverflow.com/questions/2918466/ways-to-avoid-global-temp-tables-in-oracle) – APC 2010-07-14 23:05:18

+0

检查出我回答这个以前的问题:http://stackoverflow.com/questions/2918466/ways-to-avoid-global-temp-tables-in-oracle/2918935#2918935 – APC 2010-07-14 23:23:07

+0

我已经倾倒了一个快速收藏的例子下面,尽管它重复了你更详细的答案。希望OP能够关闭这个问题。 – JulesLt 2010-07-15 08:26:50

回答

2

你在正确的方向正朝着 - 首先创建类型

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

CREATE TYPE myCollection AS TABLE OF myEntry; 

下一页一些例子功能回到您的收藏

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); 

变化的“行” - 这一次,我们使用管道,所以结果将在创建时返回到查询中。请注意,尽管是一个函数,但对于PIPELINED函数没有结束RETURN。

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); 

要使用纯内存中的数据替换你的临时表,你将需要一些东西来存储您的收藏 - 即具有状态的包。

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;