【问题标题】:Catching multiple exception at once in oracle在 oracle 中一次捕获多个异常
【发布时间】:2020-02-06 12:27:50
【问题描述】:

请告诉我是否可以在 oracle 中同时捕获多个异常。不像 1 个用户定义和 1 个是 oracle 默认值。我需要同时捕获多个用户定义的异常。请告诉我该怎么做。

谢谢!

【问题讨论】:

  • 能否提供您用于同时导致多个异常的代码?
  • 我不明白这怎么可能。你执行一个操作。它会产生异常。你捕捉到了异常。唯一可能的额外异常将来自您在处理第一个异常时所做的事情。这并不是说您可以生成异常但忽略它们并继续处理,然后最后返回并收集您忽略的所有异常。
  • 你的意思是bulk exception handling?还是DML Error Logging?如果这些都不能解决您的问题,您需要编辑您的问题,以提供有关您想要实现的目标的更多详细信息。
  • 另一种选择,你的意思是单个代码单元可能会抛出几个异常中的一个,而你的异常块需要捕获并处理抛出的任何一个?

标签: oracle exception caching plsql


【解决方案1】:

当然,如果我正确理解了这个问题的话。它被称为WHEN OTHERS。不过,人们通常误用它,尤其是在使用时

exception
  when others then 
    null;
end;

因为它成功隐藏了可能出现的任何错误。 WHEN OTHERS 在开发过程中是可以的,但在生产过程中可能真的很糟糕,特别是如果它不包含 raise

【讨论】:

    【解决方案2】:

    是的,您可以按照@Littlefoot 或批量处理错误(此处未涵盖)指示的“当其他人”执行您想要的操作。但另外,您可以在 WHEN 上有一个 OR 条件异常名称子句。它不是很有用,因为通常需要更多代码来 2 个单独的 WHEN 条件,但它是有效的语法。下面演示各种错误定义方法和异常处理。

    create table except_demo ( id integer, col1 varchar2(20));
    insert into except_demo (id, col1)
      select 5,'OK' from dual union all
      select 6,'Too Many' from dual union all 
      select 6,'Still' from dual;
    
    select id, count(*) from except_demo group by id;
    
    create or replace procedure catcher(which_in integer, select_in boolean default False)
    is
      e_user_1 exception; 
      e_user_2 exception; 
      invalid_which_range exception;  
      appErr_inactive_acct exception;
      sample_ora_error exception;
      pragma exception_init (sample_ora_error, -00060);
    
      rae exception;
      rae_num constant integer := -20100;
      pragma exception_init  (rae, -20100);  
    
      col1_value except_demo.col1%type; 
    begin
       dbms_output.put( 'Enter catcher(' || which_in || ') Result=>');
       if which_in > 8 
          then raise invalid_which_range;
       end if ;
       if select_in 
       then 
           select col1 
             into col1_value
             from except_demo
            where id = which_in;
            dbms_output.put_line('Select Successful 1 row selected.');         
       else 
           case which_in
                when 1 then raise e_user_1;
                when 2 then raise e_user_2;
                when 3 then raise appErr_inactive_acct;
                when 4 then raise sample_ora_error;
                else raise_application_error(rae_num, 'Which_In=' || which_in || ' invalid. Please specify number 1-7 only'); 
            end case;
        end if; 
    exception 
       when e_user_1         
       then dbms_output.put_line('Error e_user_1');    -- user error
    
       when e_user_2         
       then dbms_output.put_line('Error e_user_2');
    
       when no_data_found or too_many_rows        
       then dbms_output.put_line('Select except_demo where id=' || which_in ||'; Returned 0 or more than 1 row. Must return exactly 1.' );    -- oracle predefined error
    
       when sample_ora_error           
       then dbms_output.put_line('Ora Error:: ' || sqlerrm );            -- oracle error NOT predefined 
    
       when appErr_inactive_acct 
       then dbms_output.put_line('Error Account id ' || which_in || ' is inactive.');  -- user error
    
       when rae 
       then dbms_output.put_line(sqlerrm); 
    
    end catcher; 
    
    declare 
      do_select boolean; 
    begin 
        for i in 1..9
        loop
           do_select := (i between 5 and 7);
           catcher(i,do_select);
        end loop;
    exception 
        when others 
        then 
            dbms_output.put_line('Error returned from catcher=>' || sqlerrm);
            raise; 
    end ;  
    
    
    drop procedure catcher;
    drop table except_demo; 
    

    在实时环境中,dbms_output 语句将被替换,将消息和其他信息写入异常日志表,而不是 dbms_output。

    我和 Littlefoot 有一点小分歧。我坚信在开发中编写的任何东西,无论是否有意,都会在生产中运行。很多时候,让你陷入困境的是意外。因此,误用 WHEN OTHERS 的示例即使在开发中也无效

    【讨论】:

      猜你喜欢
      • 2010-09-13
      • 1970-01-01
      • 2020-05-10
      • 1970-01-01
      • 2011-09-22
      • 2020-04-26
      • 1970-01-01
      相关资源
      最近更新 更多