Как выполнить процедуру параллельно внутри пакета в plsql - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть пакет, как указано ниже:

CREATE OR REPLACE PACKAGE OT.PK_TEST IS

PROCEDURE A;

Procedure B;
Procedure C;
Procedure D;

END PK_TEST;

Тело ...

CREATE OR REPLACE PACKAGE BODY  oT.PK_TEST IS
PROCEDURE A 
IS
BEGIN
--creating all required tables
B;
c;
D;
END A;

Procedure B
IS 
BEGIN
...codes
END;

Procedure C
IS 
BEGIN
...codes
END;

Procedure D
IS 
BEGIN
...codes
END;
END PK_TEST;

Я выполняю процедуру A и процедуру B, C, D получаю вызов из процедуры.

EXEC OT.PK_TEST.A;

В результате A является первой процедурой, выполняемой в пакете. Все необходимые таблицы создаются внутри процедуры A. После этого выполняются процедуры B, C, D. Но это то, что Proceudre B, C, D не зависит друг от друга. Итак, в моем пакете процедура B запускается первой, затем запускается процедура C, а затем, наконец, выполняется процедура D. Это заняло у меня много времени, чтобы запустить пакет. Я хочу выполнить процедуру B, C, D параллельно после создания всех таблиц в процедуре A.

Как я могу выполнить все процедуры параллельно? Я учусь планировать работу. Является ли использование заданий планирования хорошим методом или есть какой-либо другой вариант?

1 Ответ

1 голос
/ 05 февраля 2020

Вот пример, который использует DBMS_JOB; это довольно просто и работает хорошо. Для более сложных случаев ищите DBMS_SCHEDULER. Идея проста: у меня есть таблица и две процедуры, которые вставят строку в эту таблицу. main процедура вызовет их одновременно .

SQL> create table test (proc varchar2(10), datum date);

Table created.

SQL> create or replace procedure p1 as
  2  begin
  3    dbms_lock.sleep(1);
  4    insert into test (proc, datum) values ('p1', sysdate);
  5  end;
  6  /

Procedure created.

SQL> create or replace procedure p2 as
  2  begin
  3    dbms_lock.sleep(15);
  4    insert into test (proc, datum) values ('p2', sysdate);
  5  end;
  6  /

Procedure created.

SQL> create or replace procedure p_main as
  2    l_job number;
  3  begin
  4    dbms_job.submit(l_job, 'p1;', sysdate, null);
  5    dbms_job.submit(l_job, 'p2;', sysdate, null);
  6    commit;
  7  end;
  8  /

Procedure created.

Тестирование:

SQL> select to_char(sysdate, 'dd.mm.yyyy hh24:mi:ss') right_now from dual;

RIGHT_NOW
-------------------
05.02.2020 19:29:50

SQL> exec p_main;

PL/SQL procedure successfully completed.

SQL> select to_char(sysdate, 'dd.mm.yyyy hh24:mi:ss') right_now from dual;

RIGHT_NOW
-------------------
05.02.2020 19:29:50            --> as you can see, RIGHT NOW is equal to the one
                               --  fetched before calling the P_MAIN procedure,
                               --  although both P1 and P2 procedures are "waiting"
                               --  some time

SQL> select job, next_date, what from user_jobs;

       JOB NEXT_DATE           WHAT
---------- ------------------- --------------------
        76 05.02.2020 19:29:50 p2;         --> both procedures are scheduled to run
        75 05.02.2020 19:29:50 p1;         --  at the same time

SQL>

Чуть позже (~ 20 секунд спустя) :

SQL> select proc, to_char(datum, 'dd.mm.yyyy hh24:mi:ss') datum From test;

PROC       DATUM
---------- -------------------
p2         05.02.2020 19:30:09        --> both procedures performed INSERT, each
p1         05.02.2020 19:29:55        --  on its own time

SQL> select job, next_date, what from user_jobs;

no rows selected                      --> after procedures have completed, there's none
                                      --  in the queue as they have been scheduled to run
                                      --  only once

SQL>
...