我正在使用SQLERRM。但是有更多的程序并行运行,因此有时SQLERRM会被其他程序覆盖。运行并行我的意思是我同时运行过程a和过程b .SQLERRM是一个全局函数,这是我的问题。如果在两个过程中抛出异常,则可能发生,过程a修改过程b中的错误消息,过程b得到错误的消息。 这些程序使用简单的结构:
BEGIN
--do something/cutted off
EXCEPTION
WHEN OTHERS THEN
write_log(SYSDATE, 'ERROR_1', SQLERRM);
END;
这些过程调用write_log,声明为
CREATE OR REPLACE PROCEDURE WRITE_LOG
(
TS_START IN DATE DEFAULT SYSDATE,
ERR_CODE IN VARCHAR DEFAULT NULL,
ERR_DESC IN VARCHAR DEFAULT NULL
)
IS
BEGIN
INSERT INTO LOG
( LOG_TS_START, LOG_ERR_CODE, LOG_ERR_DESC)
VALUES
(TS_START, ERR_CODE, ERR_DESC);
COMMIT;
END WRITE_LOG;
如何避免覆盖SQLERRM?正在写入日志,但错误消息是错误的。
答案 0 :(得分:1)
首先,摆脱PL/SQL
代码中的常见错误。
WHEN OTHERS THEN
且没有任何理性逻辑的 RAISE
只是使用,只不过是一个错误。
删除所有exception blocks
,然后重试。并遵循良好的编码实践。
答案 1 :(得分:1)
过程WRITE_LOG
未使用传入的参数来执行INSERT
。试一试:
CREATE OR REPLACE PROCEDURE WRITE_LOG
(TS_START IN DATE DEFAULT SYSDATE,
ERR_CODE IN VARCHAR DEFAULT NULL,
ERR_DESC IN VARCHAR DEFAULT NULL)
IS
BEGIN
INSERT INTO LOG
(LOG_TS_START, LOG_ERR_CODE, LOG_ERR_DESC)
VALUES
(TS_START, ERR_CODE, ERR_DESC);
COMMIT;
END WRITE_LOG;
另外,在我看来,记录错误到数据库表是绝对错误的。因为您在日志记录过程中有一个COMMIT
语句,所以您将提交所有更改,直到错误点,这很可能不是您想要做的。如果你愿意的话,你可以搞乱自主交易,但对我来说,最好的办法是登录平面文件。
分享并享受。
答案 2 :(得分:0)
写入日志表非常常见,但使用自治事务进行日志记录是标准做法。这是因为您不希望主事务中的回滚影响日志记录,或者日志记录中的提交会影响主事务。 (@BobJarvis示例不是自主的)。
显示了一个简单示例here。
日志表还需要考虑其他一些事项。首先,你应该有一个log_id,它使用sys_guid(在表上定义)或触发器上的序列。此外,使用write_log可用于区分正在编写日志消息的过程(或会话)的上下文字段。
添加此设置(包括上下文)后,再次运行过程a和过程b(同时),并在上下文中传递过程名称(a或b)。您将能够在表格中看到a和b日志消息。