powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Передача параметров в CHAIN (dbms_scheduler)
5 сообщений из 5, страница 1 из 1
Передача параметров в CHAIN (dbms_scheduler)
    #39981919
Azket
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Уважаемое сообщество,

Столкнулся с некоторым непониманием как работать с цепочками в шедулере.
Если кратко, то есть таблица в которой хранятся записи с pl/sql кодом, которые нужно запускать и потом отписываться о результатах записи. Сказали реализовать через пакет dbms_scheduler, но столкнулся с проблемой, что не знаю как передать значения переменных в цепочку.

Например:
есть такие объекты:
Код: plsql
1.
2.
3.
create table t_vv(f varchar2(1), d date);
create or replace procedure vv_proc(p varchar2) is begin insert into t_vv (f) values (p); commit; end;
create or replace procedure vv_proc_log(p varchar2) is begin update t_vv set d = sysdate where f = p; commit; end;


и такая структура:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
BEGIN
   dbms_scheduler.create_program(program_name        => 'p_vv_proc',
                                 program_type        => 'STORED_PROCEDURE',
                                 program_action      => 'vv_proc',
                                 number_of_arguments => 1,
                                 enabled             => FALSE);
   dbms_scheduler.define_program_argument(program_name      => 'p_vv_proc',
                                          argument_position => 1,
                                          argument_name     => 'p',
                                          argument_type     => 'varchar2',
                                          default_value     => '0');
   dbms_scheduler.create_program(program_name        => 'p_vv_proc_log',
                                 program_type        => 'STORED_PROCEDURE',
                                 program_action      => 'vv_proc_log',
                                 number_of_arguments => 1,
                                 enabled             => FALSE);
   dbms_scheduler.define_program_argument(program_name      => 'p_vv_proc_log',
                                          argument_position => 1,
                                          argument_name     => 'p',
                                          argument_type     => 'varchar2',
                                          default_value     => '0');
   dbms_scheduler.create_chain(chain_name => 'c_vv');
   dbms_scheduler.define_chain_step(chain_name => 'c_vv', step_name => 'S1', program_name => 'p_vv_proc');
   dbms_scheduler.define_chain_step(chain_name => 'c_vv', step_name => 'S2', program_name => 'p_vv_proc_log');
   dbms_scheduler.define_chain_rule(chain_name => 'c_vv', condition =>  'TRUE', action => 'Start S1');
   dbms_scheduler.define_chain_rule(chain_name => 'c_vv', condition => 'S1 COMPLETED', action => 'Start S2');
   dbms_scheduler.define_chain_rule(chain_name => 'c_vv', condition => 'S2 COMPLETED', action => 'END');
   dbms_scheduler.enable(NAME => 'p_vv_proc');
   dbms_scheduler.enable(NAME => 'p_vv_proc_log');
   dbms_scheduler.enable(NAME => 'c_vv');
END;



Так вот, при запуске одного значения, все норм:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
BEGIN
   dbms_scheduler.define_program_argument(program_name      => 'p_vv_proc',
                                          argument_position => 1,
                                          argument_name     => 'p',
                                          argument_type     => 'varchar2',
                                          default_value     => '1');
   dbms_scheduler.define_program_argument(program_name      => 'p_vv_proc_log',
                                          argument_position => 1,
                                          argument_name     => 'p',
                                          argument_type     => 'varchar2',
                                          default_value     => '1');
   dbms_scheduler.run_chain(chain_name => 'c_vv', start_steps => '');
END;


Но при цикле происходит безобразие:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
BEGIN
   FOR i IN '1' .. '5'
   LOOP
      dbms_scheduler.define_program_argument(program_name      => 'p_vv_proc',
                                             argument_position => 1,
                                             argument_name     => 'p',
                                             argument_type     => 'varchar2',
                                             default_value     => i);
      dbms_scheduler.define_program_argument(program_name      => 'p_vv_proc_log',
                                             argument_position => 1,
                                             argument_name     => 'p',
                                             argument_type     => 'varchar2',
                                             default_value     => i);
      dbms_scheduler.run_chain(chain_name => 'c_vv', start_steps => '');
   END LOOP;
END;


Код: plsql
1.
2.
3.
4.
5.
5	20.07.2020 17:05:17
5	20.07.2020 17:05:17
5	20.07.2020 17:05:17
5	20.07.2020 17:05:17
5	20.07.2020 17:05:17



Предполагаю, что цикл очень быстро пробегает, и все поставленные задачи в шедулер выполняются исключительно со значением параметров полученным в последней итерации. А мне нужно чтобы для каждой итерации, был свой поток выполнения цепочки.

Что я делаю не так?
...
Рейтинг: 0 / 0
Передача параметров в CHAIN (dbms_scheduler)
    #39981934
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Azket,

dbms_scheduler.run_chain выполняется асинхронно, посему либо дай имя job'у в dbms_scheduler.run_chain и проверяй dba_scheduler_running_jobs / dba_scheduler_job_log либо создай job с job_type => 'CHAIN' и используй dbms_scheduler.run_job (по умолчанию job выполнится синхронно в текущей сессии).

SY.
...
Рейтинг: 0 / 0
Передача параметров в CHAIN (dbms_scheduler)
    #39981960
Azket
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY,

Я может не так понял, но с такой доработкой ничего не поменялось:
Код: plsql
1.
2.
      dbms_scheduler.create_job(job_name => 'j_chain'||i, job_type => 'CHAIN', job_action => 'c_vv',auto_drop => true, enabled => false);
      dbms_scheduler.run_job(job_name => 'j_chain'||i,use_current_session => false);
...
Рейтинг: 0 / 0
Передача параметров в CHAIN (dbms_scheduler)
    #39981980
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Azket,

use_current_session => FALSE запускает job асинхронно, а надо синхронно. Хотя, только сейчас вспомнил что chain синхронно нельзя (steps запускаются согласно rules, т.е. в одной сессии в общем случае никак). Посему только что-то типа:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
SQL> select * from t_vv;

no rows selected

SQL> DECLARE
  2      v_job varchar2(50);
  3      v_cnt number;
  4  BEGIN
  5     FOR i IN '1' .. '5'
  6     LOOP
  7        dbms_scheduler.define_program_argument(program_name      => 'p_vv_proc',
  8                                               argument_position => 1,
  9                                               argument_name     => 'p',
 10                                               argument_type     => 'varchar2',
 11                                               default_value     => i);
 12        dbms_scheduler.define_program_argument(program_name      => 'p_vv_proc_log',
 13                                               argument_position => 1,
 14                                               argument_name     => 'p',
 15                                               argument_type     => 'varchar2',
 16                                               default_value     => i);
 17        v_job := 'C_VV_JOB' || sys_guid();
 18        v_cnt := 0;
 19        dbms_scheduler.run_chain(chain_name => 'c_vv', start_steps => '',job_name => v_job );
 20        while v_cnt = 0 loop
 21          select  count(*)
 22            into  v_cnt
 23            from  dba_scheduler_job_log
 24            where owner = user
 25              and job_name = v_job
 26              and operation = 'CHAIN_RUN';
 27        end loop;
 28     END LOOP;
 29  END;
 30  /

PL/SQL procedure successfully completed.

SQL> alter session set nls_date_format = 'MM/DD/YYYY HH24:MI:SS';

Session altered.

SQL> select * from t_vv;
2 07/20/2020 12:25:55
4 07/20/2020 12:25:56
5 07/20/2020 12:25:56
1 07/20/2020 12:25:54
3 07/20/2020 12:25:55

SQL>



SY.
...
Рейтинг: 0 / 0
Передача параметров в CHAIN (dbms_scheduler)
    #39982360
Azket
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY
т.е. в одной сессии в общем случае никак)

SY.


Блин, ну почему так, вроде dbms_scheduler такое мощное средство, да еще и CHAIN прикольный механизм, а по сути все это никак не может в многопоточность.

По итогу сделал примерно так:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
BEGIN
   dbms_scheduler.add_event_queue_subscriber(subscriber_name => 'q_vv');
end;
/
BEGIN
   FOR i IN '1' .. '3'
   LOOP
      dbms_scheduler.create_job(job_name            => 'je_vv_proc' || i,
                                job_type            => 'STORED_PROCEDURE',
                                job_action          => 'vv_proc',
                                number_of_arguments => 1,
                                enabled             => FALSE,
                                auto_drop           => true);
      dbms_scheduler.set_job_argument_value(job_name => 'je_vv_proc' || i, argument_position => 1, argument_value => i);
      dbms_scheduler.create_job(job_name            => 'je_vv_proc_log' || i,
                                job_type            => 'STORED_PROCEDURE',
                                job_action          => 'vv_proc_log',
                                event_condition     => 'tab.user_data.event_type=''JOB_SUCCEEDED'' AND tab.user_data.object_name=''JE_VV_PROC' || i || '''',
                                queue_spec          => 'sys.scheduler$_event_queue,q_vv',
                                number_of_arguments => 1,
                                enabled             => FALSE);
      dbms_scheduler.set_job_argument_value(job_name          => 'je_vv_proc_log' || i,
                                            argument_position => 1,
                                            argument_value    => i);
      dbms_scheduler.enable(NAME => 'je_vv_proc_log' || i);
      dbms_scheduler.set_attribute(NAME      => 'je_vv_proc' || i,
                                   attribute => 'raise_events',
                                   VALUE     => dbms_scheduler.job_run_completed);
      dbms_scheduler.enable(NAME => 'je_vv_proc' || i);
--      dbms_scheduler.drop_job(job_name => 'je_vv_proc_log' || i);
   END LOOP;
END;
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Передача параметров в CHAIN (dbms_scheduler)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]