Я использую таблицу журнала вместо dbms_output. Обязательно настройте как автономную транзакцию, что-то вроде (конечно, измените для ваших нужд):
create or replace package body somePackage as
...
procedure ins_log(
i_msg in varchar2,
i_msg_type in varchar2,
i_msg_code in number default 0,
i_msg_context in varchar2 default null
) IS PRAGMA AUTONOMOUS_TRANSACTION;
begin
insert into myLogTable
(
created_date,
msg,
msg_type,
msg_code,
msg_context
)
values
(
sysdate,
i_msg,
i_msg_type,
i_msg_code,
i_msg_context
);
commit;
end ins_log;
...
end;
Убедитесь, что вы, конечно, создаете свою таблицу журналов. В вашем коде, если вы выполняете много операций в цикле, вы можете захотеть регистрировать только один раз за x num операций, что-то вроде:
create or replace myProcedure as
cursor some_cursor is
select * from someTable;
v_ctr pls_integer := 0;
begin
for rec in some_cursor
loop
v_ctr := v_ctr + 1;
-- do something interesting
if (mod(v_ctr, 1000) = 0) then
somePackage.ins_log('Inserted ' || v_ctr || ' records',
'Log',
i_msg_context=>'myProcedure');
end if;
end loop;
commit;
exception
when others then
somePackage.ins_log(SQLERRM, 'Err', i_msg_context=>'myProcedure');
rollback;
raise;
end;
Обратите внимание, что автономная транзакция гарантирует, что ваш журнал stmt будет вставлен, даже если произошла ошибка и вы откатили все остальное (поскольку это отдельная транзакция).
Надеюсь, это поможет ... намного лучше, чем dbms_output;)