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

Столкнулся с некоторым непониманием как работать с цепочками в шедулере.
Если кратко, то есть таблица в которой хранятся записи с 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
20.07.2020, 17:43
    #39981934
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача параметров в CHAIN (dbms_scheduler)
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
20.07.2020, 18:43
    #39981960
Azket
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача параметров в CHAIN (dbms_scheduler)
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
20.07.2020, 19:27
    #39981980
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача параметров в CHAIN (dbms_scheduler)
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
21.07.2020, 18:43
    #39982360
Azket
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Передача параметров в CHAIN (dbms_scheduler)
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
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Передача параметров в CHAIN (dbms_scheduler) / 5 сообщений из 5, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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