我正在使用INSERT作为来自各种使用许多函数和关系的表的SELECT。 select一次返回约10行。插入多个函数的结果,但对结果做进一步处理
查询看起来像
INSERT INTO EIM_TABLE(certain columns)
select a,b,...,fn(x,y,)
现在我需要收集由fn(x,y)
返回的值,每个值连接成一个单一的变量,并开展在此基础上进一步的处理。
性能是非常关键的标准,所以要避免不必要的开销。
我正在使用INSERT作为来自各种使用许多函数和关系的表的SELECT。 select一次返回约10行。插入多个函数的结果,但对结果做进一步处理
查询看起来像
INSERT INTO EIM_TABLE(certain columns)
select a,b,...,fn(x,y,)
现在我需要收集由fn(x,y)
返回的值,每个值连接成一个单一的变量,并开展在此基础上进一步的处理。
性能是非常关键的标准,所以要避免不必要的开销。
不幸的是,返回到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
我建议与GTT路线一起对流程进行改进 - 使用多重插入来加载EIM_TABLE和全局临时表。只需加载GTT所需的最小值(可能只是函数结果)。 –
多表插入是@伟大的想法@大卫! – Ben
你需要什么样的进一步处理的呢? –