【问题标题】:Can we raise an exception within an exception?我们可以在异常中引发异常吗?
【发布时间】:2014-07-29 01:03:07
【问题描述】:

我们能否在异常中引发异常,例如在WHEN OTHERS 异常中引发RAISE my_exception

此外,我试图了解以下两种情况下的输出: (请注意,唯一的区别是异常的顺序)

场景 1

DECLARE
     lc_exception Exception;
     var1 number;
BEGIN
     select 1
     into var1
     from dual
     where 1=2;
EXCEPTION
     when lc_exception then
       dbms_output.put_line('This is my exception');

     when no_data_found then
       raise lc_exception;

     when others then
        dbms_output.put_line('There could be some other exception');
END;

场景 2

DECLARE
     lc_exception Exception;
     var1 number;
BEGIN
     select 1
     into var1
     from dual
     where 1=2;
EXCEPTION
     when no_data_found then
       raise lc_exception; 

     when lc_exception then
       dbms_output.put_line('This is my exception');

     when others then
        dbms_output.put_line('There could be some other exception');
END;

【问题讨论】:

  • 是的,您可以在异常处理程序中引发另一个异常。
  • 请您也回答上述2个场景
  • @NoobEditor --> 在提出我的问题之前,我已经完成了上述线程。我相信我的问题与上述线程有点不同(如果你经历了场景)。无论如何,非常感谢您的帮助.... :)

标签: oracle plsql


【解决方案1】:

两种情况都有类似的错误堆栈:

ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at line 20
ORA-01403: no data found

唯一的区别是引发用户定义异常的确切位置(第 20 行与第 18 行)。

  1. 选择不匹配任何行,因此 no_data_found 由 Oracle 引发 - ORA-01403: no data found 在错误堆栈中。
  2. 异常被块的异常处理程序块捕获。
  3. 在异常处理程序中引发了用户定义的异常lc_exception
  4. 由于程序没有其他异常处理程序,用户定义的异常被泄露到主机环境(在我的情况下是 sqlplus 客户端)-ORA-06510: PL/SQL: unhandled user-defined exception 并且程序终止。

两种情况下的异常传播相似,因为在两种情况下都会引发相同的初始异常no_data_found,并且只有一个异常处理块。因此no_data_foundlc_exception 处理程序的顺序无关紧要。

有关异常处理/传播的更详细说明,请参见:Oracle 文档中的PL/SQL Error Handling

【讨论】:

  • 非常感谢 user272735
【解决方案2】:

您只需要一个异常处理程序来捕获您的本地异常。如果您在异常处理程序中引发异常,则无法在同一个异常处理程序中捕获它。

DECLARE
  lc_exception EXCEPTION;
  var1 number;
BEGIN
  BEGIN
    SELECT 1
    INTO var1
    FROM dual
    WHERE 1=2;
  EXCEPTION -- this is where the exception will be raised
    WHEN no_data_found THEN 
      raise lc_exception;
  END;

  dbms_output.put_line( 'This will never be executed.' );

EXCEPTION -- this is where the exception will be caught
  WHEN lc_exception THEN
    dbms_output.put_line( 'This is my exception' );

  WHEN others THEN
    dbms_output.put_line( 'There could be some other exception' );
END;

但是,您可能需要考虑一种稍微不同的方法。

DECLARE
  lc_exception EXCEPTION;
  PRAGMA EXCEPTION_INIT( lc_exception, -20222 );
  var1 NUMBER;
BEGIN
  BEGIN
    SELECT 1
    INTO var1
    FROM dual
    WHERE 1=2;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN 
    RAISE_APPLICATION_ERROR( -20222, 'This is my exception' );
  END;

  DBMS_OUTPUT.PUT_LINE( 'This will never be executed.' );

EXCEPTION
    WHEN lc_exception THEN
      DBMS_OUTPUT.PUT_LINE( SQLERRM );

    WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE( 'Some other exception: ' || SQLERRM );
END;

【讨论】:

  • 非常感谢 TomCatt :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-11
  • 2011-03-22
  • 2023-01-20
  • 1970-01-01
  • 2015-12-30
  • 1970-01-01
  • 2012-10-31
相关资源
最近更新 更多