我有一個程序列表,按給定順序調用表中的所有行。而不是硬編碼過程調用,我想將它們全部添加到單獨的表中,並循環遍歷包含調用每個過程的過程的行。所有程序都需要相同的輸入參數。使用名稱的字符串表示形式調用PLSQL存儲過程
這是可能的嗎?
我有一個程序列表,按給定順序調用表中的所有行。而不是硬編碼過程調用,我想將它們全部添加到單獨的表中,並循環遍歷包含調用每個過程的過程的行。所有程序都需要相同的輸入參數。使用名稱的字符串表示形式調用PLSQL存儲過程
這是可能的嗎?
說你有這個表:
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)
假設你有一個表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;
獲取所有執行的程序。
它在這個例子可能是矯枉過正,但對於這種事情,你可以封裝的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
它可能不會給你買多少在這個例子中,但它是值得銘記的一種方法。
精彩,非常感謝! – bjelleklang