2013-08-31 32 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