テーブル内のすべての行に対して、指定された順序で呼び出されるプロシージャのリストがあります。プロシージャ呼び出しをハードコーディングするのではなく、それらをすべて別のテーブルに追加し、それぞれを呼び出すプロシージャを含む行をループしたいと思います。すべての手順には同じ入力パラメータが必要です。名前の文字列表現を使用して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;
すべての手順を実行することができます。
それは、この例ではやり過ぎおそらくだが、ループは単に「タスク」タイプを定義
r.task.run();
ような何かを実行できるように、この種のもののためにあなたは、タイプ定義内
execute immediate
をカプセル化することができます:
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);
いくつかのデモの手順:
それぞれを実行する保存されたタスク210〜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