Есть ли какой-либо способ отслеживать строки, вставленные функцией Oracle в базу данных

#stored-procedures #plsql #oracle10g #oracle-sqldeveloper #stored-functions

#хранимые процедуры #plsql #oracle10g #oracle-sqldeveloper #сохраненные функции #хранимые функции

Вопрос:

У меня есть процедура для обновления баланса с даты начала до даты окончания, а также я хочу отслеживать количество вставляемых записей. Я использую dbms_output.put_line, чтобы получить количество вставленных записей, но это не дает никаких выходных данных, когда выполнение завершается, выводится результат подсчета. Код процедуры выглядит следующим образом :

 create or replace function updatebal(start_date IN DATE, end_date IN DATE)
RETURN NUMBER 
IS
difference number;
curr_r  number;
BEGIN 
difference := end_date - start_date;
curr_r := 0;
while curr_r <= difference LOOP
curr_r := curr_r   10;
for curr_in in 1..10 LOOP
date_value := date_value  1 ;
insertAvailBal(date_value);
commit;
select count(*) into totalCount from avail_bal;
dbms_output.put_line('total count' || totalCount);
end loop;
END LOOP;
RETURN 1;
END;
  

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

Ответ №1:

Как Тони уже ответил: вы не можете изменить поведение dbms_output.

Рекомендуемый способ передачи сигналов о ходе выполнения за пределы хранимой процедуры — использовать dbms_application_info пакет для управления информацией в v$session_longops

Вы даже можете управлять отдельными индикаторами выполнения для внешнего и внутреннего цикла. v$session_longops будет даже отображаться оценка того, сколько времени займет процесс, на основе средней продолжительности с течением времени. Эти оценки довольно точны, если время выполнения для каждого (сообщаемого) шага является достаточно постоянным.

Вы можете улучшить свою функцию следующим образом:

 create or replace function updatebal(start_date IN DATE, end_date IN DATE)
  RETURN NUMBER 
IS
  difference number;
  curr_r  number;
  main_index binary_integer;
  sub_index  binary_integer;
  main_slno  binary_integer;
  sub_slno   binary_integer;

BEGIN 
  difference := end_date - start_date;
  curr_r := 0;

  -- initialize the module information
  dbms_application_info.set_module('updatebal', 'Calculate Balance');

  -- initialize two different "handles" for the inner and outer loop
  main_index := dbms_application_info.set_session_longops_nohint;
  sub_index := dbms_application_info.set_session_longops_nohint;

  while curr_r <= difference LOOP
    curr_r := curr_r   10;

    -- report each outer step
    dbms_application_info.set_session_longops(rindex => main_index, 
            slno => main_slno, 
            op_name => 'main loop', 
            sofar => curr_r, 
            totalwork => difference);

    for curr_in in 1..10 LOOP

      date_value := date_value  1;

      insertAvailBal(date_value);
      commit;

      select count(*) into totalCount from avail_bal;

      -- report each inner step with the totalcount
      dbms_application_info.set_session_longops(
                      rindex => sub_index, 
                      slno => sub_slno, 
                      op_name => 'Sub Loop, totalcount'||totalcount, 
                      sofar => curr_in, totalwork => 10);

    end loop;
  END LOOP;

  RETURN 1;

  dbms_application_info.set_module(null,null);
END;
/
  

Смотрите руководство для получения более подробной информации:
https://docs.oracle.com/database/121/ARPLS/d_appinf.htm#ARPLS003

Ответ №2:

Вот как работает dbms_output, он отображает все свои выходные данные после завершения запуска, вы не можете отслеживать это в режиме реального времени.

Если вам действительно нужен этот мониторинг прогресса в режиме реального времени, вы могли бы использовать процедуру с автономной транзакцией для вставки сообщений в специальную таблицу, а затем из другого сеанса вы могли бы просматривать содержимое этой таблицы, пока процесс все еще выполняется.

Пример такой процедуры:

 procedure log_message (p_message varchar2) is
   pragma autonomous_transaction;
begin
   insert into message_table (message) values (p_message);
   commit;
end;