Параллельная обработка в Oracle

У меня была «процедура A», в которой она должна вернуть нулевой курсор во внешний интерфейс, а затем немедленно продолжить следующий шаг, в котором она вызовет процедуру, которая займет 20 минут для завершения процедуры.

Procedure A(cur_out refcursor)
begin

 OPEN cur_out  for
 select 
 null empname,
 null empid
 from dual;

procedure B();//Will take 20 min

end;

Здесь «Процедура A» должна вернуть нулевой курсор, не дожидаясь завершения «Процедуры B».

Как это реализовать в оракуле.

Заранее спасибо.


person K Ratnajyothi    schedule 05.10.2010    source источник


Ответы (1)


Предполагая, что вам не нужно, чтобы процедура B выполнялась в том же сеансе, что и A, вы можете запланировать выполнение задания асинхронно, т.е.

CREATE OR REPLACE PROCEDURE a( p_cur_out OUT SYS_REFCURSOR )
AS
  l_jobno pls_integer;
BEGIN
  OPEN p_cur_out 
   FOR SELECT cast( null as varchar2(64) ) empname, 
              cast( null as integer ) empid
         FROM dual;

  dbms_job.submit( l_jobno,
                   'BEGIN B(); END;' );
  commit;
END a;

Вы вернетесь из A, и задание будет немедленно запланировано для запуска процедуры B в отдельном сеансе (обратите внимание, что задание не начнется, пока текущий сеанс не будет зафиксирован, поэтому я добавил здесь фиксацию - если ваш код собирается чтобы совершить в другом месте, вы можете устранить это). Все, что делает dbms_job.submit, — это создает задание — задание не начнет выполняться до тех пор, пока процедура не вернется.

Если B принимает аргументы, вам потребуется динамически построить блок PL/SQL. Итак, если B принимает два параметра NUMBER

CREATE OR REPLACE PROCEDURE a( p_cur_out OUT SYS_REFCURSOR )
AS
  l_jobno  pls_integer;
  l_param1 pls_integer;
  l_param2 pls_integer;
BEGIN
  OPEN p_cur_out 
   FOR SELECT cast( null as varchar2(64) ) empname, 
              cast( null as integer ) empid
         FROM dual;

  dbms_job.submit( l_jobno,
                   'BEGIN B(' || to_char( l_param1 ) || ', ' ||
                                 to_char( l_param2 ) || '); END;' );
  commit;
END a;
person Justin Cave    schedule 05.10.2010
comment
Я не могу думать ни о каком другом пути. Запуск двух потоков в одной транзакции кажется совершенно невозможным. - person Thilo; 05.10.2010
comment
Это нормально... Но есть небольшое сомнение.. Если 'Proecure a' будет ждать dbms_job.submit l_jobno,'BEGIN B(); КОНЕЦ;' ); для завершения или просто он будет запущен, и процедура будет завершена. - person K Ratnajyothi; 05.10.2010
comment
Он ожидает завершения DBMS_JOB.SUBMIT, да. Но это происходит почти мгновенно. Процедура B будет выполнена через некоторое время в отдельном сеансе. - person Justin Cave; 05.10.2010
comment
Еще одно сомнение, если процедура B имеет некоторые аргументы, такие как B(arg1,arg2)... Как запланировать эту процедуру B с помощью dbms_job.submit.......dbms_job.submit(l_jobno,'BEGIN B(arg1 ,arg2); END;);.........Поскольку он выдает ошибки при передаче этих аргументов таким образом... нужно ли нам следовать некоторому формату при передаче аргументов в процедуру B, которая является dbms_job . - person K Ratnajyothi; 05.10.2010
comment
СОЗДАЙТЕ ИЛИ ЗАМЕНИТЕ ПРОЦЕДУРУ a(l_param1 varchar2(20), l_param2 varchar2(20), p_cur_out OUT SYS_REFCURSOR ) AS l_jobno pls_integer; BEGIN OPEN p_cur_out FOR SELECT cast(null as varchar2(64)) empname, cast(null as integer) empid FROM dual; dbms_job.submit( l_jobno, 'BEGIN B(' || l_param1 || ', ' || l_param2 || '); END;' ); совершить; КОНЕЦ а; - person K Ratnajyothi; 05.10.2010
comment
вот как мы выполняем .................................declare TYPE gui_ref_cur IS REF CURSOR; p_cur_out gui_ref_cur; BEGIN A('MOBILE','5/10/2010 10:00:00',p_cur_out); КОНЕЦ; /.................................столкнулись со следующей ошибкой............... ...........................................ORA-06550: строка 1, столбец 148: PLS-00103: Обнаружен символ 10 при ожидании одного из следующих: ), * & | = - + ‹ / › at in is mod остаток not rem =› .. ‹показатель степени (**)› ‹› или != или ~= ›= ‹= ‹› и или - person K Ratnajyothi; 05.10.2010
comment
@K Ratnajyothi- Параметры хранимой процедуры объявляются как VARCHAR2, а не VARCHAR2 (20). - person Justin Cave; 05.10.2010
comment
Исправил объявление как varchar2, но не как varchar2(20).......... Тем не менее, это показывает ту же проблему, что и упомянутая. а также мы запускаем задание dbmsjob, которое было отправлено как dbms_job.run(l_jobno);.............. но не выполнено должным образом - person K Ratnajyothi; 05.10.2010
comment
Можете ли вы опубликовать подпись B? Вы ожидаете, что вторым параметром A действительно будет DATE? - person Justin Cave; 05.10.2010