Есть job, который запускает процедуру с входящими параметрами через программу. Как запустить job вовремя ее выполнения чтобы она стала в очередь и начала отрабатывать после завершения первой, но уже с другими параметрами?
job запускаю след образом
dbms_scheduler.set_job_argument_value('GPIMS.JOB_UPD_GP_ADDR_MAPP',1,IN_GP_ID);
dbms_scheduler.set_job_argument_value('GPIMS.JOB_UPD_GP_ADDR_MAPP',2,to_char(P_GP_STATUS_DATE));
dbms_scheduler.enable('GPIMS.JOB_UPD_GP_ADDR_MAPP');
Создание job
begin
dbms_scheduler.create_job('GPIMS.JOB_UPD_GP_ADDR_MAPP',
program_name => 'GPIMS.PROGRAM_UPD_GP_ADDR_MAPP',
auto_drop => FALSE);
end;
Создание программы
begin
sys.dbms_scheduler.create_program(program_name => 'GPIMS.PROGRAM_UPD_GP_ADDR_MAPP',
program_type => 'STORED_PROCEDURE',
program_action => 'GPIMS.PKG_GLOBAL_PROBLEM.UPD_GP_ADDR_MAPP',
number_of_arguments => 3,
enabled => false,
comments => '');
sys.dbms_scheduler.define_program_argument(program_name => 'GPIMS.PROGRAM_UPD_GP_ADDR_MAPP',
argument_position => 1,
argument_name => 'IN_GP_ID',
argument_type => 'VARCHAR2',
default_value => '');
sys.dbms_scheduler.define_program_argument(program_name => 'GPIMS.PROGRAM_UPD_GP_ADDR_MAPP',
argument_position => 2,
argument_name => 'P_GP_STATUS_DATE',
argument_type => 'DATE',
default_value => '');
sys.dbms_scheduler.define_program_argument(program_name => 'GPIMS.PROGRAM_UPD_GP_ADDR_MAPP',
argument_position => 3,
argument_name => 'OUT_MSG',
argument_type => 'VARCHAR2',
default_value => '');
sys.dbms_scheduler.enable(name => 'GPIMS.PROGRAM_UPD_GP_ADDR_MAPP');
end;
Ответ
Так нельзя делать. Невозможно запустить once Job, который уже выполняется.
Для этого есть цепочки (job chains), но передать к каждому звену цепочки свои параметры также не представляется возможным.
Можно передать каждому звену мета данные, например: job_name, job_subname, как формальные параметры. Они будут замещены актуальными значениями для выполняемой задачи и соответственно звена задачи. Далее определить эти же данные как ключ в таблице для параметров.
Подготовим схему:
create table myJobInfo (beg timestamp, end timestamp, info varchar2 (256));
create or replace type myJobArgs as object (
jobName varchar2 (32), jobStepName varchar2 (32), argChar varchar2 (64), argDate date);
/
create table myJobArgsTab of myJobArgs;
insert into myJobArgsTab
select myJobArgs (
'myJob', 'chainStep'||rownum, 'arg char '||rownum, date'2018-07-01'+(rownum-1))
from xmlTable ('1 to 3');
Создадим программу и цепочку выполненения, которая будет запускать эту программу в каждом звене:
begin
sys.dbms_scheduler.create_program (
program_name=>'myJobProg',
program_type=>'stored_procedure',
program_action=>'myJobProc',
number_of_arguments=>2,
enabled=>false,
comments=>'test job')
;
dbms_scheduler.define_metadata_argument (
program_name=>'myJobProg',
metadata_attribute=>'job_name',
argument_position=>1
);
dbms_scheduler.define_metadata_argument (
program_name=>'myJobProg',
metadata_attribute=>'job_subname',
argument_position=>2
);
sys.dbms_scheduler.enable ('myJobProg');
-- create chain/steps
dbms_scheduler.create_chain ('myJobChain');
dbms_scheduler.define_chain_step ('myJobChain', 'chainStep1', 'myJobProg');
dbms_scheduler.define_chain_step ('myJobChain', 'chainStep2', 'myJobProg');
dbms_scheduler.define_chain_step ('myJobChain', 'chainStep3', 'myJobProg');
-- rules
dbms_scheduler.define_chain_rule ('myJobChain', condition=>'true', action=>'start chainStep1');
dbms_scheduler.define_chain_rule ('myJobChain', condition=>'chainStep1 completed', action=>'start chainStep2');
dbms_scheduler.define_chain_rule ('myJobChain', condition=>'chainStep2 completed', action=>'start chainStep3');
dbms_scheduler.define_chain_rule ('myJobChain', condition=>'chainStep3 completed', action=>'end');
dbms_scheduler.enable ('myJobChain');
end;
/
Тест процедура:
create or replace procedure myJobProc (jobName varchar2, jobStepName varchar2) is
rowid_ rowid;
args myJobArgs;
begin
begin
select value (t) into args
from myJobargsTab t
where upper (t.jobName) = myJobProc.jobName
and upper (t.jobStepName) = myJobProc.jobStepName
for update
;
exception when others then
dbms_output.put_line ('ERROR: '||jobName||'.'||JobStepName||': sqlerrm:'||sqlerrm);
end;
insert into myJobInfo (beg, info) values (
systimestamp, jobName||'.'||JobStepName||': args='||args.argChar||'/'||to_char (args.argDate,'yyyy-mm-dd'))
returning rowid into rowid_
;
sys.dbms_lock.sleep (3);
update myJobInfo set end=systimestamp where rowid=rowid_;
end;
/
Запустим всю цепочку и посмотрим, что получилось:
exec dbms_scheduler.run_chain (chain_name=>'myJobChain', start_steps=>null, job_name=>'myJob');
select * from myJobInfo order by beg desc;
BEG END INFO
------------ ------------ ----------------------------------------------------------------
10:52:24.246 10:52:27.246 MYJOB.CHAINSTEP3: args=arg char 3/2018-07-03
10:52:21.202 10:52:24.202 MYJOB.CHAINSTEP2: args=arg char 2/2018-07-02
10:52:18.154 10:52:21.154 MYJOB.CHAINSTEP1: args=arg char 1/2018-07-01
Для дальнейшей информации читаем оф. документацию тут и тут
Комментариев нет:
Отправить комментарий