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
吗?
谢谢!!
答案 0 :(得分:2)
从 documentation ,
SQL语句无法调用SQLCODE或SQLERRM。使用他们的价值观 在SQL语句中,首先将它们分配给局部变量
也是
除了使用FORALL语句及其SAVE EXCEPTIONS子句之外,Oracle建议使用DBMS_UTILITY.FORMAT_ERROR_STACK
因此,对于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);
答案 1 :(得分:1)
从技术上讲,其他人的建议是正确的:在“其他人例外”块中执行的“插入”操作实际上将在日志表中插入新行。
问题是这样的插入语句将成为主过程同一事务的一部分,并且由于您在执行它时出错,因此您很可能回滚该事务,这也会回滚日志表中的插入
我想您面临的问题不是您没有成功记录错误消息:而是您随后将其回滚,以及您在同一事务中所做的所有其他写操作。
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;
/
P.S:我的代码中可能有一些错别字:由于目前无法访问oracle服务器,我现在无法对其进行测试。