【发布时间】:2016-03-17 11:14:32
【问题描述】:
我有一个主存储过程:
MASTER();
在这个存储过程中,我调用了另外 3 个存储过程:
SP1();
SP2();
SP3();
现在,它正在连续运行,即一个接一个。我想并行运行它,一旦所有 3 个存储过程完全执行,运行 MASTER() 存储过程的下一部分。
我使用的是 Oracle Standard One Edition 11.2。我怎样才能做到这一点?
【问题讨论】:
我有一个主存储过程:
MASTER();
在这个存储过程中,我调用了另外 3 个存储过程:
SP1();
SP2();
SP3();
现在,它正在连续运行,即一个接一个。我想并行运行它,一旦所有 3 个存储过程完全执行,运行 MASTER() 存储过程的下一部分。
我使用的是 Oracle Standard One Edition 11.2。我怎样才能做到这一点?
【问题讨论】:
一种存档方法是使用DBMS_JOB 或DBMS_SCHEDULER 并行启动程序,并在它们完成时使用DBMS_ALERT 通知主程序。
【讨论】:
还有其他方法可以实现这一点。
设置环境:
create table t_procedure(id number, procedures varchar2(200));
create type l_char is table of varchar2(100);
create procedure goSleeep(p_sec number)is
begin
dbms_lock.sleep( p_sec );
end;
包装:
create or replace package goParallel is
TYPE t_referential_cursor IS REF CURSOR RETURN t_procedure%ROWTYPE;
function runParallel(p_cursor t_referential_cursor)
return l_char pipelined
parallel_enable(partition p_cursor BY HASH(id));
end;
create or replace package body goParallel is
function runParallel(p_cursor t_referential_cursor)
return l_char pipelined
parallel_enable(partition p_cursor BY HASH(id))
is
v_start date := sysdate;
v_end date;
vid number;
p_proc varchar2(200);
begin
loop
fetch p_cursor into vid, p_proc;
exit when p_cursor%notfound;
execute immediate p_proc;
v_end := sysdate;
pipe row( vid||' --- '||to_char(v_start,'HH24:MI:SS')||' - '|| to_char(v_end,'HH24:MI:SS'));
end loop;
return;
end;
end;
插入一些程序运行。
insert into t_procedure values (1, 'begin goSleeep(5); end;');
insert into t_procedure values (2, 'begin goSleeep(8); end;');
insert into t_procedure values (3, 'begin goSleeep(9); end;');
commit;
并以奇怪的方式运行它。
select * from table(goParallel.runParallel(cursor(select /*+ PARALLEL(a 8) */ * from t_procedure a)));
-- result: id - start - end
1 --- 12:15:54 - 12:15:59
2 --- 12:15:54 - 12:16:02
3 --- 12:15:54 - 12:16:03
【讨论】: