oracle 无法处理PL/SQL中引发的异常错误

70gysomp  于 2023-01-01  发布在  Oracle
关注(0)|答案(2)|浏览(139)

我尝试在未找到行时处理异常。结果,我看到以下错误:PL/SQL: unhandled user-defined exception. A user-defined exception was raised by PL/SQL code, but not handled.我做错了什么?

DECLARE
  my_exception EXCEPTION;
  result1 VARCHAR2(50);
  result2 NUMBER;
BEGIN
  SELECT brand, year INTO result1, result2 FROM cars WHERE car_id=200;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    RAISE my_exception;  WHEN my_exception THEN
    DBMS_OUTPUT.PUT_LINE('Exception has been thrown');
END;
z4bn682m

z4bn682m1#

您成功地捕获了NO_DATA_FOUND异常,但是在该异常处理程序中,您引发了自己的新用户定义异常(RAISE my_exception)。
当你从这样的异常处理程序引发时,它福尔斯到父代码块,并在那里寻找异常处理程序......但是你没有父代码块,如此类推,直到它到达最外层的代码块,如果没有被捕获,它最终会向客户端抛出“未处理的用户定义异常”。
如果您想继续执行,只发出dbms_output消息,那么删除“RAISE my_exception”行以及与该异常有关的所有操作。只需将dbms_output放在NO_DATA_FOUND的处理程序中。
然而,如果你真的想使用用户定义的异常,那么把整个异常嵌套在一个 Package 父块中,并在那里处理它:

DECLARE
  my_exception exception;
BEGIN
   DECLARE
     result1 VARCHAR2(50);
     result2 NUMBER;
   BEGIN
      SELECT brand, year INTO result1, result2 FROM cars WHERE car_id=200;
   EXCEPTION
     WHEN NO_DATA_FOUND THEN
       RAISE my_exception;
   END;
EXCEPTION
  WHEN my_exception THEN
    dbms_output.put_line("my_exception raised")
END;
wydwbb8l

wydwbb8l2#

当引发NO_DATA_FOUND异常时,外部块中的异常处理程序已被调用。如果在异常处理块中引发另一个异常,则不会在同一级别捕获该异常;相反,您需要:
1.将RAISE语句 Package 在其自己的PL/SQL匿名块中,并在该块的异常处理程序中捕获异常:

DECLARE
  my_exception EXCEPTION;
  result1 VARCHAR2(50);
  result2 NUMBER;
BEGIN
  SELECT brand, year INTO result1, result2 FROM cars WHERE car_id=200;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    BEGIN
      RAISE my_exception;
    EXCEPTION
      WHEN my_exception THEN
        DBMS_OUTPUT.PUT_LINE('Exception has been thrown');
    END;
END;
/

1.将引发异常的块 Package 在外部块中,并在那里捕获异常:

DECLARE
  my_exception EXCEPTION;
BEGIN
  DECLARE
    result1 VARCHAR2(50);
    result2 NUMBER;
  BEGIN
    SELECT brand, year INTO result1, result2 FROM cars WHERE car_id=200;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      RAISE my_exception;
  END;
EXCEPTION
  WHEN my_exception THEN
    DBMS_OUTPUT.PUT_LINE('Exception has been thrown');
END;
/

这两个输出:

Exception has been thrown

fiddle

相关问题