Страницы

Поиск по вопросам

пятница, 7 июня 2019 г.

Oracle job queue

Есть 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
Для дальнейшей информации читаем оф. документацию тут и тут

Комментариев нет:

Отправить комментарий