这是我正在努力改编的一段Oracle代码。我已经缩写了所有细节:
declare
begin
loop
--do stuff to populate a global temporary table. I'll call it 'TempTable'
end loop;
end;
/
Select * from TempTable
现在,只要我分两步运行它,这个查询运行正常。 首先我在顶部运行程序,然后我运行select *来获取结果。
是否可以组合这两个部分,以便我可以填充全局临时表并一步检索结果?
提前致谢!
答案 0 :(得分:1)
嗯,对我而言,这取决于我将如何看待这些步骤。您正在执行PL / SQL和SQL命令。我宁愿在文件中键入它们,并在一个命令中运行它们(如果这可以作为一个步骤调用)...
像
这样的东西file.sql
begin
loop
--do stuff to populate a global temporary table. I'll call it 'TempTable'
end loop;
end;
/
Select *
from TempTable
/
并按以下方式运行:
prompt> sqlplus /@db @file.sql
如果您向我们提供更多详细信息,例如您如何填充GTT,或许我们可以找到一种方法,只需一步即可完成。
答案 1 :(得分:0)
是的,但这并非无足轻重。
create global temporary table my_gtt
( ... )
on commit preserve rows;
create or replace type my_gtt_rowtype as object
( [columns definition] )
/
create or replace type my_gtt_tabtype as table of my_gtt_rowtype
/
create or replace function pipe_rows_from_gtt
return my_gtt_tabtype
pipelined
is
pragma autonomous_transaction;
type rc_type is refcursor;
my_rc rc_type;
my_output_rec my_gtt_rectype := my_gtt_rectype ([nulls for each attribute]);
begin
delete from my_gtt;
insert into my_gtt ...
commit;
open my_rc for select * from my_gtt;
loop
fetch my_rc into my_output_rec.attribute1, my_output_rec.attribute1, etc;
exit when my_rc%notfound;
pipe_row (my_output_rec);
end loop;
close my_rc;
return;
end;
/
我不知道自治事务编译指示是否需要 - 但我怀疑它是,否则会抛出执行DML的函数的错误。
我们使用这样的代码来生成无法执行过程逻辑的报告引擎构建他们在各种子报告中使用(并重用)的全局临时表。
答案 2 :(得分:0)
在oracle中,很少需要一个存储中间结果的额外表。它可能有助于使事情更容易理解。当您能够编写SQL来填充中间表时,您当然可以在一个步骤中查询行,而无需通过填充GTT来浪费时间。如果您使用pl / sql填充GTT,请查看是否可以将其更正为纯SQL。这几乎肯定会给你带来性能上的好处。