Это, вероятно, избыточна в этом примере, но для такого рода вещи можно инкапсулировать 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