我有一个以给定顺序为表中的所有行调用的过程列表。我想将它们全部添加到一个单独的表中,而不是硬编码过程调用,并遍历包含调用每个过程的过程的行。所有过程都需要相同的输入参数。
这一切都可能吗?
答案 0 :(得分:5)
说你有这张桌子:
create table procs(procName) as (
select 'proc1' from dual union all
select 'proc2' from dual union all
select 'proc3' from dual
)
和这些程序:
create or replace procedure proc1(p1 in varchar2, p2 in number) is begin dbms_output.put_line('running Proc1(' || p1 || ', ' || p2 || ')'); end;
create or replace procedure proc2(p1 in varchar2, p2 in number) is begin dbms_output.put_line('running Proc2(' || p1 || ', ' || p2 || ')'); end;
create or replace procedure proc3(p1 in varchar2, p2 in number) is begin dbms_output.put_line('running Proc3(' || p1 || ', ' || p2 || ')'); end;
您可以尝试:
declare
yourParameter1 varchar2(10) := 'X';
yourParameter2 number := 10;
begin
for i in ( select procName from procs order by procName) loop
execute immediate 'begin ' || i.procName || '(:1, :2); end;' using yourParameter1, yourParameter2;
end loop;
end;
你得到了什么:
running Proc1(X, 10)
running Proc2(X, 10)
running Proc3(X, 10)
答案 1 :(得分:2)
我们假设您有一个表procedures_to_run
,其中列name
处理要运行的过程的名称,id
确定它们的顺序。你可以打电话:
begin
for x in (select name from procedures_to_run order by id) loop
execute immediate 'call '|| x.name ||'(INPUT_PARAMS)';
end loop;
end;
执行所有程序。
答案 2 :(得分:1)
在这个例子中可能有些过分,但是对于这种事情,你可以将execute immediate
封装在一个类型定义中,这样循环就可以执行类似r.task.run();
的东西
定义一项任务'类型:
create or replace type task as object
( command varchar2(100)
, member procedure run );
/
create or replace type body task
as
member procedure run
is
begin
execute immediate 'begin ' || self.command || '; end;';
exception
when others then
raise_application_error(-20000, 'Command failed: ' || self.command, true);
end run;
end;
/
现在你的桌子可以有一个'任务'列而不是普通字符串:
create table demo_tasks
( created_tate date default sysdate not null
, last_run_date date
, succeeded_yn varchar2(1) check (succeeded_yn in ('Y','N'))
, task task not null );
一些演示程序:
create or replace procedure p1 as begin dbms_output.put_line('This is ' || $$plsql_unit); end;
/
create or replace procedure p2 as begin dbms_output.put_line('This is ' || $$plsql_unit); end;
/
create or replace procedure p3 as begin dbms_output.put_line('This is ' || $$plsql_unit); end;
/
insert into demo_tasks (task) values (task('p1'));
insert into demo_tasks (task) values (task('p2'));
insert into demo_tasks (task) values (task('p3'));
循环执行每个任务的存储任务:
begin
for r in (
select * from demo_tasks
)
loop
-- Add code here to update run date, status etc
r.task.run();
end loop;
end;
/
This is P1
This is P2
This is P3
在这个例子中,它可能不会给你带来太大的影响,但作为一种方法,它值得记住。