【发布时间】:2017-04-15 03:31:22
【问题描述】:
我遇到了一个问题,即当我捕获异常时原始堆栈跟踪会丢失,然后引发它。
- 在 proc_a 中抛出异常
- 捕获异常。
- 执行回滚。
- 引发异常。
- 捕获异常(父块)
- 打印堆栈跟踪:
SUBSTR(SQLERRM || chr(10) || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE(), 1, 3999)
示例:
DECLARE
BEGIN
DECLARE
lv_val VARCHAR2(1);
BEGIN
SELECT dummy INTO lv_val -- Line# 6 (desired)
FROM dual
WHERE dummy = 'FFF';
EXCEPTION
WHEN OTHERS THEN
--DBMS_OUTPUT.PUT_LINE(SUBSTR(SQLERRM || chr(10) || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE(), 1, 3999));
RAISE; -- Line# 12 (actual)
END;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SUBSTR(SQLERRM || chr(10) || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE(), 1, 3999));
END;
/
期望的结果:
原始异常的行号(第 1 步)。
ORA-01403: no data found
ORA-06512: at line 6
或
ORA-01403: no data found
ORA-06512: at line 12
Caused By:
ORA-01403: no data found
ORA-06512: at line 6
实际结果:
RAISE 的行号(第 4 步)。
ORA-01403: no data found
ORA-06512: at line 12
其他失败的尝试:
SQLERRM || chr(10) || DBMS_UTILITY.FORMAT_ERROR_STACK()
ORA-01403: no data found
ORA-01403: no data found
SQLERRM || chr(10) || DBMS_UTILITY.FORMAT_CALL_STACK()
ORA-01403: no data found
----- PL/SQL Call Stack -----
object line object
handle number name
0xee1cbd68 18 anonymous block
【问题讨论】:
-
我不认为这是可能的。你已经在你的yedtion中说过:“当我捕获异常时”,即异常在异常处理程序中解决。
-
并非如此。我已经在使用
DBMS_UTILITY.FORMAT_ERROR_BACKTRACE()。而DBMS_UTILITY.FORMAT_ERROR_STACK()只显示消息,这两个消息都是相同的,因为它被捕获然后引发。DBMS_UTILITY.FORMAT_CALL_STACK也给出了错误的行号。 -
一旦异常被抓到了,相信你也没有办法再抓到了;你不能避免内部
WHEN OTHERS并在外部异常处理部分进行回滚和任何你需要的事情吗? -
我有时会检查
dbms_utility.format_error_backtrace是否已经包含sqlerrm,然后再连接它们。然而,这是一个老问题(我怀疑这不是 PL/SQL 独有的——例如,我在 Perl 中遇到过同样的情况)。有关异常处理的量子力学的一些说明,请参阅mikesmithers.wordpress.com/2015/07/24/…。
标签: oracle exception plsql raise