2013-08-31 31 views
2

我正在使用INSERT作爲來自各種使用許多函數和關係的表的SELECT。 select一次返回約10行。插入多個函數的結果,但對結果做進一步處理

查詢看起來像

INSERT INTO EIM_TABLE(certain columns) 
select a,b,...,fn(x,y,) 

現在我需要收集由fn(x,y)返回的值,每個值連接成一個單一的變量,並開展在此基礎上進一步的處理。

性能是非常關鍵的標準,所以要避免不必要的開銷。

+0

你需要什麼樣的進一步處理的呢? –

回答

1

不幸的是,返回到INSERT語句子句只能與值被用來條款的話,這不會是相當漂亮,因爲它可能是。

如果您想要重複使用您插入的數據而不選擇它兩次,則需要將其放置在可以重新使用的位置。這可以是GLOBAL TEMPORARY TABLE (GTT)或用戶定義的類型。

就個人而言,我更喜歡一種類型,因爲我認爲他們更靈活;你想要做什麼取決於你之後必須做什麼處理。如果你需要對結果執行SQL,那麼GTT將會更合適。

如果您想使用用戶定義的類型執行某些操作,請將其與BULK COLLECT;它可能看起來像下面這樣。

重點是聲明一個遊標,它是你想要創建的SELECT語句;然後聲明一個可以容納該SELECT語句值的類型。然後您將所有數據收集到該類型中。一旦你完成了,你可以將它插入到任何地方並執行任何你想要的其他操作。一般來說,最好是在SQL中而不是在PL/SQL中執行所有的操作。除非您確定使用PL/SQL更快,否則不要進行進一步的處理。

declare 

    cursor c_stuff is 
    select a, b, ..., fn(x, y) as fn 
     from somewhere; 

    type t__stuff is table of c_stuff%rowtype index by binary_integer; 
    t_stuff t__stuff; 

    l_new_stuff varchar2(100); 

begin 

    open c_stuff; 
    fetch c_stuff bulk collect into t_stuff; 
    close t_stuff; 

    forall i in t_stuff.first .. t_stuff.last 
     insert into somewhere_else values (t_stuff(i)); 

    for i in t_stuff.first .. t_stuff.last loop 
     l_new_stuff := l_new_stuff || t_stuff(i).fn; 
    end loop; 

    ... 

如果你走下GTT路線,那麼它看起來更容易一些。創建一個與您的SELECT語句具有相同數據類型的表:

create global temporary table gtt_stuff (
    a number 
    , b ... 
    , fn ...) 
    on commit delete rows; 

然後將INSERT插入此表中;您將能夠操作表格中的數據並像普通表格一樣使用它。如果您指定PRESERVE ROWS,則數據將一直保留到事務結束時使用DELETE ROWS,直到會話結束。

你說你是串聯的fn()結果,因此很可能是這樣的:

select listagg(fn) within group (order by 1) 
    into l_new_stuff 
    from gtt_stuff; 

還要注意大衛·阿爾德里奇的(大)的建議,在評論中,你也可以使用一個多表插入,這樣你可以插入GTT 您同時表:

insert all 
    into gtt_stuff values (a, ..., fn) -- only necessary columns 
    into somewhere_else values (a, b, ..., fn) 
select a, b, ..., fn 
    from somewhere 
+1

我建議與GTT路線一起對流程進行改進 - 使用多重插入來加載EIM_TABLE和全局臨時表。只需加載GTT所需的最小值(可能只是函數結果)。 –

+0

多表插入是@偉大的想法@大衛! – Ben