Как вставить результат dbms_output.put_line в таблицу для перехвата ошибок? - PullRequest
0 голосов
/ 28 ноября 2018
Exception
WHEN OTHERS THEN
--dbms_output.put_line('pl_update_sidm_user r: ERROR CODE:' || sqlcode || '~' || 
--sqlerrm || ' EMPL_NBR:' || r.EMPL_NBR);

insert into ERROR_MSG (ERROR_MSG_ID,ERROR_MSG) values (ERROR_MSG_ID_SEQ.NEXTVAL, 'pl_update_sidm_user_duty_role r2');
END;

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

Могу ли я поместить результат dbms_output в таблицу в виде строки?

Если нет, могу ли я получить sqlcode,sqlerrm без использования dbms_output?

Спасибо !!

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Технически то, что предлагают другие, является правильным: операция «вставка», выполняемая в блоке «исключение, когда другие», фактически вставит новую строку в таблицу журнала.

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

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

Oracle дает вам возможность выполнить код в отдельной транзакции, используя процедуры «автономной транзакции».

вам нужно создать такую ​​процедуру:

create or replace  procedure Write_Error_log(
              arg_error_code number, 
              arg_error_msg varchar2, 
              arg_error_backtrace varchar2) is
 PRAGMA AUTONOMOUS_TRANSACTION;
 begin
    INSERT INTO error_msg (
          error_msg_id, 
          error_code, 
          error_msg, 
          error_stack)
     VALUES (
          error_msg_id_seq.NEXTVAL, 
          arg_error_code,
          arg_error_msg,  
          arg_error_backtrace);
     commit; -- you have to commit or rollback always, before exiting a 
             -- pragma autonomous_transaction procedure
 end; 

Что эта процедура делает, чтобы записать новую запись в таблицу журнала, используя совершенно отдельный и независимыйТранзитная транзакция: данные останутся в таблице журнала, даже если вы выполните откат в своей вызывающей процедуре.Вы также можете использовать такую ​​процедуру для создания общего журнала (не только ошибок).

Все, что вам нужно сделать сейчас, это вызвать описанную выше процедуру всякий раз, когда вам нужно что-то записать, поэтому ваш код становится:

DECLARE
   v_errcode NUMBER;
   v_errmsg VARCHAR2(1000);
BEGIN
   --some other statements that may raise exception.
EXCEPTION WHEN OTHERS THEN
     Write_Error_log(SQLCODE, SQLERRM, dbms_utility.format_error_backtrace);
END;
/

PS: в моем коде могут быть некоторые опечатки: я не могу проверить это сейчас, так как в данный момент не могу получить доступ к серверу оракула.

0 голосов
/ 28 ноября 2018

Из документации ,

Оператор SQL не может вызвать SQLCODE или SQLERRM.Чтобы использовать их значения в операторе SQL, сначала присвойте их локальным переменным

Кроме того,

Oracle рекомендует использовать DBMS_UTILITY.FORMAT_ERROR_STACK, кроме случаев использования оператора FORALL с его SAVEИСКЛЮЧЕНИЕ предложение

Итак, для SQLCODE или SQLERRM вы должны назначить их в переменные и использовать их.

DECLARE
v_errcode NUMBER;
v_errmsg VARCHAR2(1000);
BEGIN
--some other statements that may raise exception.
EXCEPTION
WHEN OTHERS THEN
v_errcode := SQLCODE;
v_errmsg  := SQLERRM;
insert into ERROR_TABLE (ERROR_MSG_ID,ERROR_MSG) --change your table name
values (ERROR_MSG_ID_SEQ.NEXTVAL,
      v_errcode||':'||v_errmsg); 

END;
/

Предпочтительно использовать вместо этого вставку, как указано вРекомендация Oracle.

insert into ERROR_TABLE (ERROR_MSG_ID,ERROR_MSG) values (ERROR_MSG_ID_SEQ.NEXTVAL,
      DBMS_UTILITY.FORMAT_ERROR_STACK);

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...