在PL/SQL(Oracle)中,异常可以跨函数/过程调用传播吗?

pop*_*ack 1 oracle plsql stored-procedures exception-handling function

因为它发生在封闭的块中
如果一个匿名块调用一个引发异常的函数,那些既不会显示在控制台上也不会被封闭在块中......
更有甚者,在被函数中的处理程序捕获后,在匿名函数调用之后的行块正常执行!

被叫程序是:

CREATE OR REPLACE PROCEDURE qt(pno number, qty OUT number)
IS
BEGIN
select sum(qty_on_hand) into qty from products where productno=pno;
END;
Run Code Online (Sandbox Code Playgroud)

调用块是:

DECLARE
qty number;
BEGIN
qt(&pno, qty);
dbms_output.put_line('qty is: '||qty);
END;
Run Code Online (Sandbox Code Playgroud)

如果产品编号无效,则不会显示错误; 为什么?

Ton*_*ews 8

如果异常被函数中的处理程序捕获并且没有重新引发,那么将不会在调用者中触发异常.这是正确的行为.如果您希望调用程序可以看到异常,则必须使用以下RAISE命令在函数中重新引发该异常:

FUNCTION fun ...
...
EXCEPTION
  WHEN some_exception THEN
    ...
    RAISE;
END;
Run Code Online (Sandbox Code Playgroud)

或者,您可以提出不同的例外,例如

EXCEPTION
  WHEN some_exception THEN
    ...
    RAISE_APPLICATION_ERROR(-20001,'My error message');
END;
Run Code Online (Sandbox Code Playgroud)


Dav*_*sta 6

在您的具体示例中,我认为根本没有例外.您说"如果产品编号无效",我认为您的意思是产品编号不存在.听起来你希望你的查询抛出NO_DATA_FOUND,但由于它使用的是没有GROUP BY的聚合函数,它实际上会返回包含NULL没有匹配行的单行.