我们有一个处理数据库中很多记录的程序。现在有时如果程序花费的时间过长,则用户手动取消该程序,从而抛出ORA-01013 EXCEPTION。但是,我们仍然想知道在取消程序之前处理了多少记录。
我们尝试生成在EXCEPTION WHEN OTHERS
块中调用的日志,但该块中的任何代码似乎都不起作用。我们甚至试图通过PRAGMA INIT EXCEPTION
为ORA-01013提出一个EXCEPTION但没有用。代码似乎达到了异常但不执行任何代码。我猜测,由于该过程被取消,EXCEPTION块中的代码没有时间做任何事情而只是关闭。
知道如何获取在取消程序之前处理的记录的计数?每次commit
发生时我都可以尝试增加记录,但是想知道是否有更好的方法来实现这个目标
答案 0 :(得分:4)
您可以在autonomous transaction中记录进度。
即。通过AT将处理后的行记录在单独的事务(具有自己的提交)中的日志表中,例如:
CREATE OR REPLACE
PROCEDURE log_progress (
p_id IN NUMBER,
p_data IN VARCHAR2
)
AS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO log_table
(
id,
logging_data
)
VALUES
(
p_id,
p_data
);
--
COMMIT;
EXCEPTION
WHEN others
THEN
-- Log the error here
...
-- Re-raise if needed
RAISE;
END;
如果进程被取消,那么您可以查询AT记录的数据,并查找已处理的行数,因为日志表中的记录插入不会被“主”事务回滚。
另一种方法是使用UTL_FILE包写入日志文件,然后在取消交易时读取文件内容。
顺便说一下,您可以将(几乎所有)您想要的代码放入异常部分,如果引发该异常,它将被执行。必须有另一个原因导致您的代码未被运行或被导致异常引发的事务回滚。http://www.exforsys.com/tutorials/oracle-11g/oracle-11g-exception-handling.html
希望它有所帮助...
答案 1 :(得分:2)
我刚刚经历了同样的事情 - 这似乎是一个没有记录的错误:
ORA-01013根本没有被其他人捕获......我必须添加一个明确的WHEN ORA-01013 Block以捕获并处理异常......尽管文档明确指出,当其他人将捕获所有RUNTIME例外时 - .-
测试代码:
此代码应始终打印'EXCEPTION OTHERS',但会在11g上打印'EXCEPTION CANCELED' - 是否有人可以确认此行为?
DECLARE
e_cancelled EXCEPTION;
PRAGMA EXCEPTION_INIT(e_cancelled, -1013);
BEGIN
BEGIN
RAISE e_cancelled;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('EXCEPTION OTHERS');
END;
EXCEPTION
WHEN e_cancelled THEN
DBMS_OUTPUT.PUT_LINE('EXCEPTION CANCELLED');
END;
/