Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
ArchiSQL
Member

Откуда:
Сообщений: 123
Есть основной джоб. Из него циклом запускаются новые джобы, которые параллельно собирают данные на сервер. По завершении сбора (то есть после того как вызванные джобы пройдут), нужно продолжить выполнение старого\вызвать новый джоб с процедурой обработки собранных данных.
Пока приходит только идея с записью во временную таблицу по завершении каждого джоба и триггер на эту таблицу, после апдейта проверяется кол-во записей в этой таблице, если оно равно определенному значению, запускается новый джоб с процедурой обработки собранных данных. Но как то это "кустарно".
У кого-нибудь еще есть идеи как это реализовать?
11 фев 19, 16:08    [21806581]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 9399
DBMS_SCHEDULER chain.

SY.
11 фев 19, 16:16    [21806599]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
ArchiSQL
Member

Откуда:
Сообщений: 123
SY,

спасибо, пошел читать документацию!
11 фев 19, 16:47    [21806637]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
ArchiSQL
Member

Откуда:
Сообщений: 123
Погуглил, получилось сделать, но не нравится, что хардкодом. У меня около 40 chain_step' ов, которые состоят из процедуры proc(i), где i= 1...40. То есть:
BEGIN
DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain', 'proc_1', 'my_program1');
DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain', 'proc_2', 'my_program2');
..............
END;

proc_1 = proc(1); proc_2 = proc(2).....

Нагуглил, что "There is no direct way of passing parameters to a chain step on the fly but there is a way to workaround it.".
https://community.oracle.com/message/9666831#9664831
Там есть ссылка на пример, но все равно ясности не появилось как делать. Ну и пример 2007 года, может что новое появилось в этом плане.
То есть не хочется создавать 40 отдельных программ, с каждой программой связывать 40 стэпов, а потом передавать это все в define_chain_rule, учитывая, что каждая программа - это одна и та же ХП с разными параметрами.
Может кто-то сталкивался, буду благодарен за пример или ссылочку где эта проблема подробно описана.
Спасибо.
12 фев 19, 15:58    [21807582]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
Vadim Lejnin
Member

Откуда:
Сообщений: 6613
ArchiSQL
Погуглил, получилось сделать, но не нравится, что хардкодом. У меня около 40 chain_step' ов, которые состоят из процедуры proc(i), где i= 1...40. То есть:
BEGIN
DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain', 'proc_1', 'my_program1');
DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain', 'proc_2', 'my_program2');
..............
END;

proc_1 = proc(1); proc_2 = proc(2).....

Нагуглил, что "There is no direct way of passing parameters to a chain step on the fly but there is a way to workaround it.".
https://community.oracle.com/message/9666831#9664831
Там есть ссылка на пример, но все равно ясности не появилось как делать. Ну и пример 2007 года, может что новое появилось в этом плане.
То есть не хочется создавать 40 отдельных программ, с каждой программой связывать 40 стэпов, а потом передавать это все в define_chain_rule, учитывая, что каждая программа - это одна и та же ХП с разными параметрами.
Может кто-то сталкивался, буду благодарен за пример или ссылочку где эта проблема подробно описана.
Спасибо.

Может проще все это сделать в одной процедуре?
12 фев 19, 16:03    [21807590]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
Elic
Member

Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
Сообщений: 28823
ArchiSQL
Есть основной джоб. Из него циклом запускаются новые джобы, которые параллельно собирают данные на сервер. По завершении сбора (то есть после того как вызванные джобы пройдут), нужно продолжить выполнение старого\вызвать новый джоб с процедурой обработки собранных данных.
Параллельная обработка данных из процедуры
12 фев 19, 16:04    [21807591]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
ArchiSQL
Member

Откуда:
Сообщений: 123
Vadim Lejnin,

так если я делаю в одной процедуре - где распараллеливание? Там же будет выполняться все последовательно, собственно сейчас так и есть. Ведь вся суть состоит в том, что скрипты через дблинки обращаются к нескольким серверам, сейчас это все происходит последовательно, занимает много времени, я хочу сделать параллельно.
Или я Вас неправильно понял?
12 фев 19, 16:48    [21807642]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
ArchiSQL
Member

Откуда:
Сообщений: 123
Elic,

Спасибо, я думал над таким вариантом (правда думал делать через системное представление dba_jobs_running), но хочется спросить вот что - если к примеру ночью запустился job, процедура зависла, получается цикл loop будет крутиться все время, пока не сделаешь дисконнект сессии вручную. К примеру если тебя нет несколько дней на работе и все это время цикл крутится - такая практика будет считаться нормальной?
12 фев 19, 16:55    [21807651]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
MazoHist
Member

Откуда:
Сообщений: 83
ArchiSQL,
версия сервера? джобики 1-40 должны/могут выполняться параллельно? DBMS_PARALLEL_EXECUTE.create_chunks_by_sql
12 фев 19, 17:04    [21807659]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 9399
Прекрасно обходится чeрез global context. Step1 устанавливает global context variables в значения параметров всех процедур. Step2 - Step41 выполняются параллельно по завершении Step1 и есть:

BEGIN
    PROC1(SYS_CONTEXT('CONTEXT_NAME','PROCx_PAR1'),...SYS_CONTEXT('CONTEXT_NAME','PROCx_PARn'));
END;


SY.
12 фев 19, 17:14    [21807668]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
Elic
Member

Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
Сообщений: 28823
ArchiSQL
К примеру если тебя нет несколько дней на работе и все это время цикл крутится - такая практика будет считаться нормальной?
Тут как и "кому кобыла невеста".
12 фев 19, 17:28    [21807682]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
ArchiSQL
Member

Откуда:
Сообщений: 123
SY
Прекрасно обходится чeрез global context. Step1 устанавливает global context variables в значения параметров всех процедур. Step2 - Step41 выполняются параллельно по завершении Step1 и есть:

BEGIN
    PROC1(SYS_CONTEXT('CONTEXT_NAME','PROCx_PAR1'),...SYS_CONTEXT('CONTEXT_NAME','PROCx_PARn'));
END;


SY.


Сейчас у меня нечто подобное:

+

-- Create chain
BEGIN
DBMS_SCHEDULER.CREATE_CHAIN (
   chain_name            =>  'my_chain',
   rule_set_name         =>  NULL,
   evaluation_interval   =>  NULL,
   comments              =>  NULL);
END;
/

-- Create 40 programs which contain the same procedure "proc" with different parameters and 1 program that analyze previously collected data (after proc(i) finished)
begin
    for i in 1 .. 40 loop
      --dbms_output.put_line(
      execute immediate
              'begin' || chr(10) ||
              'DBMS_SCHEDULER.CREATE_PROGRAM (' || chr(10) ||
              '   PROGRAM_NAME          => ''MY_PROGRAM'|| i||  chr(10) ||
              '   PROGRAM_TYPE          => ''PLSQL_BLOCK'',' || chr(10) ||
              '   PROGRAM_ACTION        => ''BEGIN proc(' || i ||
              '); END;'',' || chr(10) ||
              '   NUMBER_OF_ARGUMENTS   => 0,' || chr(10) ||
              '   ENABLED               => TRUE,' || chr(10) ||
              '   COMMENTS              => ''my_chain'');' || chr(10) ||
              'end;'
             ;
              --);
    end loop;
end;

begin 
DBMS_SCHEDULER.CREATE_PROGRAM (
   PROGRAM_NAME          => 'MY_PROGRAM_ANALYZE',
   PROGRAM_TYPE          => 'PLSQL_BLOCK',
   PROGRAM_ACTION        => 'BEGIN analyse_data(); END;',
   NUMBER_OF_ARGUMENTS   => 0,
   ENABLED               => TRUE,
   COMMENTS              => 'my_chain');
end;
/

-- Define 41 chain_steps accosiated with 41 programs created before 
begin
    for i in 1 .. 40 loop  
      execute immediate
      --dbms_output.put_line(
          'BEGIN' || chr(10) ||
          'DBMS_SCHEDULER.DEFINE_CHAIN_STEP(''my_chain'', ''step' || i || '' || ''', ''MY_PROGRAM' || i || ''')' || ';' || chr(10) ||
          'END;'/*)*/;
    end loop;  
end;

BEGIN
    DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain', 'step_analize', 'MY_PROGRAM_ANALYZE');
END;
/

--- define corresponding rules for the chain.
BEGIN
DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain', 'TRUE', 'START ' || 
'step1,step2,step3,step4,step5,step6,step7,step8,step9,step10,step11,step12,step13,step14, ' || 
'step15,step16,step17,step18,step19,step20,step21,step22,step23,step24,step25,step26,step27,step28, ' || 
'step29,step30,step31,step32,step33,step34,step35,step36,step37,step38,step39,step40');
DBMS_SCHEDULER.DEFINE_CHAIN_RULE (
   'my_chain', 'step1 COMPLETED and step2 COMPLETED and step3 COMPLETED and step4 COMPLETED and step5 COMPLETED and step6 COMPLETED and step7 COMPLETED and ' || 
'step8 COMPLETED and step9 COMPLETED and step10 COMPLETED and step11 COMPLETED and step12 COMPLETED and step13 COMPLETED and step14 COMPLETED and ' || 
'step15 COMPLETED and step16 COMPLETED and step17 COMPLETED and step18 COMPLETED and step19 COMPLETED and step20 COMPLETED and step21 COMPLETED and ' || 
'step22 COMPLETED and step23 COMPLETED and step24 COMPLETED and step25 COMPLETED and step26 COMPLETED and step27 COMPLETED and step28 COMPLETED and ' || 
'step29 COMPLETED and step30 COMPLETED and step31 COMPLETED and step32 COMPLETED and step33 COMPLETED and step34 COMPLETED and step35 COMPLETED and ' || 
'step36 COMPLETED and step37 COMPLETED and step38 COMPLETED and step39 COMPLETED and step40 COMPLETED', 
'Start step_analize');
DBMS_SCHEDULER.DEFINE_CHAIN_RULE ('my_chain', 'step_analize COMPLETED', 'END');
END;
/

--- enable the chain
BEGIN
  DBMS_SCHEDULER.ENABLE('my_chain');
END;
/

begin
  dbms_scheduler.run_chain(chain_name => 'my_chain');
end;




Не понимаю, как мне могут помочь глобальные контекстные переменные. Если при создании программ я еще могу сделать нечто подобное (взял из статьи Пржиялковского), указав параметр number_of_arguments :
+
CREATE PROCEDURE salary ( deer NUMBER ) AS 
BEGIN UPDATE emp SET sal = sal - deer; 
END;
/

BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM
( program_name        => 'simple_program1'
, program_type        => 'STORED_PROCEDURE'
, program_action      => 'salary'
, enabled             => FALSE
, number_of_arguments => 1 
) ;
END;
/


Но как сделать так, чтобы не было 40 отдельных степов....
13 фев 19, 09:27    [21808040]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
ArchiSQL
Member

Откуда:
Сообщений: 123
MazoHist
ArchiSQL,
версия сервера? джобики 1-40 должны/могут выполняться параллельно? DBMS_PARALLEL_EXECUTE.create_chunks_by_sql


12с. По хорошему должны выполняться параллельно. Про parallel_execute сейчас почитаю, спасибо.
13 фев 19, 09:29    [21808042]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 9399
Глобальный контекст создается один раз. Всe шаги создаются один раз. Первый шаг присваивает значения параметров 40-ка параллельных шагов переменным контeкста. Параллельные шаги выполняются по завершении первого шага. Каждый из них использует соосветствующие значения глобального контекста вместо того что было раньше передано как параметр (тупо делаем обертку). Последний шаг выполняется после завершения (successful) параллельных шагов.

SY.
13 фев 19, 15:36    [21808602]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
ArchiSQL
Member

Откуда:
Сообщений: 123
ArchiSQL
MazoHist
ArchiSQL,
версия сервера? джобики 1-40 должны/могут выполняться параллельно? DBMS_PARALLEL_EXECUTE.create_chunks_by_sql


12с. По хорошему должны выполняться параллельно. Про parallel_execute сейчас почитаю, спасибо.


Вроде бы получилось - то что я хотел - 40 процедур запускаются параллельно, по завершении всех этих процедур запускается еще одна процедура, которая обрабатывает собранные данные.

Упрощенно выглядит так:

DECLARE
  l_task     VARCHAR2(30) := 'test_task';
  l_stmt     CLOB;
  l_sql_stmt VARCHAR2(32767);
BEGIN
  DBMS_PARALLEL_EXECUTE.create_task (task_name => l_task);

  l_stmt := 'select level as col, level as col from dual connect by level < 41';

  DBMS_PARALLEL_EXECUTE.create_chunks_by_sql(task_name => l_task,
                                             sql_stmt  => l_stmt,
                                             by_rowid  => FALSE);

  l_sql_stmt := 'BEGIN dbms_lock.sleep(10); proc(:start_id, :end_id); END;';

  DBMS_PARALLEL_EXECUTE.run_task(task_name => l_task,
                                 sql_stmt  => l_sql_stmt,
                                 language_flag => DBMS_SQL.NATIVE,
                                 parallel_level => 40);                            

  analyse_data();

  DBMS_PARALLEL_EXECUTE.drop_task(l_task);
END;
/
13 фев 19, 17:04    [21808738]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
ArchiSQL
Member

Откуда:
Сообщений: 123
SY
Глобальный контекст создается один раз. Всe шаги создаются один раз. Первый шаг присваивает значения параметров 40-ка параллельных шагов переменным контeкста. Параллельные шаги выполняются по завершении первого шага. Каждый из них использует соосветствующие значения глобального контекста вместо того что было раньше передано как параметр (тупо делаем обертку). Последний шаг выполняется после завершения (successful) параллельных шагов.

SY.


Спасибо, завтра на свежую голову подумаю на Вашими словами, хочется с chain также сделать, очень понравилась гибкость пакета DBMS_SCHEDULER :)
13 фев 19, 17:07    [21808742]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
ArchiSQL
Member

Откуда:
Сообщений: 123
SY
Глобальный контекст создается один раз. Всe шаги создаются один раз. Первый шаг присваивает значения параметров 40-ка параллельных шагов переменным контeкста. Параллельные шаги выполняются по завершении первого шага. Каждый из них использует соосветствующие значения глобального контекста вместо того что было раньше передано как параметр (тупо делаем обертку). Последний шаг выполняется после завершения (successful) параллельных шагов.

SY.


Я Вас правильно понял, что вот здесь:
begin
    for i in 1 .. 40 loop
      --dbms_output.put_line(
      execute immediate
              'begin' || chr(10) ||
              'DBMS_SCHEDULER.CREATE_PROGRAM (' || chr(10) ||
              '   PROGRAM_NAME          => ''MY_PROGRAM'|| i||  chr(10) ||
              '   PROGRAM_TYPE          => ''PLSQL_BLOCK'',' || chr(10) ||
              '   PROGRAM_ACTION        => ''BEGIN proc(' || i ||
              '); END;'',' || chr(10) ||
              '   NUMBER_OF_ARGUMENTS   => 0,' || chr(10) ||
              '   ENABLED               => TRUE,' || chr(10) ||
              '   COMMENTS              => ''my_chain'');' || chr(10) ||
              'end;'
             ;
              --);
    end loop;
end;


я i заменяю на SYS_CONTEXT('CONTEXT_NAME','PROC_PAR' || i), предварительно создав глобальную контекстную переменную:

CREATE OR REPLACE PROCEDURE set_mycontext_value ( par IN VARCHAR2, val IN VARCHAR2 ) 
AS BEGIN  DBMS_SESSION.SET_CONTEXT ( 'CONTEXT_NAME', par, val ); END;

CREATE OR REPLACE CONTEXT CONTEXT_NAME USING set_mycontext_value;

BEGIN 
 set_mycontext_value ('PROC_PAR1', '1'); 
 set_mycontext_value ('PROC_PAR2', '2'); 
.....
END;


Я все равно не могу понять - у нас все так же 40 программ и все так же будет 40 созданных шагов. В чем преимущество или я неправильно Вас понял?
19 фев 19, 15:05    [21814386]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
ArchiSQL
Member

Откуда:
Сообщений: 123
SY
Прекрасно обходится чeрез global context. Step1 устанавливает global context variables в значения параметров всех процедур. Step2 - Step41 выполняются параллельно по завершении Step1 и есть:

BEGIN
    PROC1(SYS_CONTEXT('CONTEXT_NAME','PROCx_PAR1'),...SYS_CONTEXT('CONTEXT_NAME','PROCx_PARn'));
END;


SY.



И почему здесь у функции PROC1 кол-во параметров равно n?
19 фев 19, 15:06    [21814388]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
MazoHist
Member

Откуда:
Сообщений: 83
ArchiSQL
Я все равно не могу понять - у нас все так же 40 программ и все так же будет 40 созданных шагов. В чем преимущество или я неправильно Вас понял?

CHAIN удобно использовать когда у нас сильно "ветвистая" логика - 1 -2 потом 3-4 параллельно потом если что-то неудачно то 5 если все удачно то 6. Если у нас 40 почти одинаковых процессов которые запускаются одновременно, а потом вне зависимости от их исхода выполняется еще что-то, то DBMS_PARALLEL_EXECUTE - то что доктор прописал.
19 фев 19, 15:39    [21814429]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
ArchiSQL
Member

Откуда:
Сообщений: 123
MazoHist
ArchiSQL
Я все равно не могу понять - у нас все так же 40 программ и все так же будет 40 созданных шагов. В чем преимущество или я неправильно Вас понял?

CHAIN удобно использовать когда у нас сильно "ветвистая" логика - 1 -2 потом 3-4 параллельно потом если что-то неудачно то 5 если все удачно то 6. Если у нас 40 почти одинаковых процессов которые запускаются одновременно, а потом вне зависимости от их исхода выполняется еще что-то, то DBMS_PARALLEL_EXECUTE - то что доктор прописал.


Да, с помощью DBMS_PARALLEL_EXECUTE (Вам спасибо за подсказку по этому пакету) я уже сделал, сейчас тестируется, теперь хочу с chain разобраться что SY имел ввиду с контекстными переменными - я скорее всего его мысль не уловил, иначе у меня смысла использования контекстных переменных нет.
19 фев 19, 16:03    [21814461]     Ответить | Цитировать Сообщить модератору
 Re: Распараллеливание джобов. Продолжение работы после завершения выполнения вызванных джобов.  [new]
ArchiSQL
Member

Откуда:
Сообщений: 123
SY, Вы имели ввиду такую реализацию с глобальными контекстными переменными?

+

CREATE TABLE CHAIN_TEST (
       i number,
       status char(1),
       dt date,
       session_id number
);
/       

--select * from CHAIN_TEST order by dt,i, status
--truncate table CHAIN_TEST

CREATE OR REPLACE PROCEDURE proc(i NUMBER) as
BEGIN
  insert into CHAIN_TEST
  VALUES (i, 'B', sysdate, SYS_CONTEXT('userenv','SESSIONID'));
  commit;
  
  dbms_lock.sleep(i);
  insert into CHAIN_TEST
  VALUES (i, 'E', sysdate, SYS_CONTEXT('userenv','SESSIONID'));
  commit;
END;
/


CREATE OR REPLACE PROCEDURE analyse_data as
BEGIN
  proc(20);
END;
)

------------/*1. Global context variable*/------------
CREATE OR REPLACE CONTEXT globalcontext
USING globalcontext_pkg
ACCESSED GLOBALLY
/

CREATE OR REPLACE PACKAGE globalcontext_pkg AS
       PROCEDURE set_value (
         par varchar2
       , val varchar2
       );
END;
/

CREATE OR REPLACE PACKAGE BODY globalcontext_pkg AS
       PROCEDURE set_value (
         par varchar2
       , val varchar2
       ) 
       AS
       BEGIN
         DBMS_SESSION.SET_CONTEXT (
            'globalcontext'
          , par
          , val
         );
       END; 
END;
/

--select * from all_objects where = 'globalcontext_pkg'
------------/*2. Create chain*/------------
BEGIN
DBMS_SCHEDULER.CREATE_CHAIN (
   chain_name            =>  'my_chain',
   rule_set_name         =>  NULL,
   evaluation_interval   =>  NULL,
   comments              =>  NULL);
END;
/

------------/*3. Define parameters (global context variables)*/------------
begin 
DBMS_SCHEDULER.CREATE_PROGRAM (
   PROGRAM_NAME          => 'PROGRAM_SET_PAR',
   PROGRAM_TYPE          => 'PLSQL_BLOCK',
   PROGRAM_ACTION        => 'begin' || chr(10) ||
                            '  for i in 1 .. 10 loop' || chr(10) ||
                            '     globalcontext_pkg.set_value (''PROC_PAR''||i, to_char(i));' || chr(10) ||
                            '  end loop;' || chr(10) ||
                            'end;',
   NUMBER_OF_ARGUMENTS   => 0,
   ENABLED               => TRUE,
   COMMENTS              => 'DEFINE_PARAMETERS');
end;
/

------------/*4. Define 10 PARALLEL_PROGRAM*/------------

begin
    for i in 1 .. 10 loop
      --dbms_output.put_line(
      execute immediate
              'begin' || chr(10) ||
              'DBMS_SCHEDULER.CREATE_PROGRAM (' || chr(10) ||
              '   PROGRAM_NAME          => ''PARALLEL_PROGRAM'|| i ||''',' || chr(10) ||
              '   PROGRAM_TYPE          => ''PLSQL_BLOCK'',' || chr(10) ||
              '   PROGRAM_ACTION        => ''BEGIN proc(SYS_CONTEXT(''''globalcontext'''',''''PROC_PAR'|| i||''''')' ||
              '); END;'',' || chr(10) ||
              '   NUMBER_OF_ARGUMENTS   => 0,' || chr(10) ||
              '   ENABLED               => TRUE,' || chr(10) ||
              '   COMMENTS              => ''PARALLEL_PROCEDURE'||i||''');' || chr(10) ||
              'end;'
              ;
              --);
    end loop;
end;

------------/*5. Define BLOCK after PARALLEL execution*/------------
begin 
DBMS_SCHEDULER.CREATE_PROGRAM (
   PROGRAM_NAME          => 'PROGRAM_FINAL',
   PROGRAM_TYPE          => 'PLSQL_BLOCK',
   PROGRAM_ACTION        => 'BEGIN analyse_data(); END;',
   NUMBER_OF_ARGUMENTS   => 0,
   ENABLED               => TRUE,
   COMMENTS              => 'BLOCK_AFTER_PARALLEL_EXECUTION');
end;
/

------------/*6. Define steps*/------------
BEGIN
    DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain', 'step0', 'PROGRAM_SET_PAR');
END;
/


begin
    for i in 1 .. 10 loop  
      execute immediate
      --dbms_output.put_line(
          'BEGIN' || chr(10) ||
          'DBMS_SCHEDULER.DEFINE_CHAIN_STEP(''my_chain'', ''step' || i ||'' || ''', ''PARALLEL_PROGRAM' || i || ''')' || ';' || chr(10) ||
          'END;';
          --);
    end loop;
end;


BEGIN
    DBMS_SCHEDULER.DEFINE_CHAIN_STEP('my_chain', 'final_step', 'PROGRAM_FINAL');
END;
/

------------/*7. Define rules*/------------
BEGIN
  DBMS_SCHEDULER.DEFINE_CHAIN_RULE('my_chain', 'TRUE', 'START step0');
  DBMS_SCHEDULER.DEFINE_CHAIN_RULE
           ('my_chain', 'step0 COMPLETED', 
            'START step1,step2,step3,step4,step5,step6,step7,step8,step9,step10');
  DBMS_SCHEDULER.DEFINE_CHAIN_RULE (
            'my_chain', 'step1 COMPLETED and step2 COMPLETED and step3 COMPLETED and ' || 
            'step4 COMPLETED and step5 COMPLETED and step6 COMPLETED and step7 COMPLETED and ' || 
            'step8 COMPLETED and step9 COMPLETED and step10 COMPLETED', 
            'Start final_step');
  DBMS_SCHEDULER.DEFINE_CHAIN_RULE ('my_chain', 'final_step COMPLETED', 'END');
END;
/

------------/*8. Enable the chain*/------------
BEGIN
  DBMS_SCHEDULER.ENABLE('my_chain');
END;
/

------------/*9. Run chain*/------------
begin
  dbms_scheduler.run_chain(chain_name => 'my_chain', start_steps => 'step0');
end;
20 фев 19, 16:13    [21815556]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить