Oracle:使用RAISE_APPLICATION_ERROR的情况如何?

Ric*_*cky 18 oracle

我们可以使用RAISE来触发异常.我们需要使用RAISE_APPLICATION_ERROR的具体情况是什么?

谢谢.

APC*_*APC 29

RAISE_APPLICATION_ERROR有两种用途.第一种是用我们自己的,更有意义的消息替换通用的Oracle异常消息.第二种是创建我们自己的异常条件,而Oracle不会抛出它们.

以下过程说明了这两种用法.它强制执行一项业务规则,即将来不能聘用新员工.它还会覆盖两个Oracle异常.一个是DUP_VAL_ON_INDEX,它由一个唯一键引发EMP(ENAME).另一个是在违反EMP(MGR)和之间的外键EMP(EMPNO)(因为经理必须是现有员工)时抛出的用户定义的异常.

create or replace procedure new_emp
    ( p_name in emp.ename%type
      , p_sal in emp.sal%type
      , p_job in emp.job%type
      , p_dept in emp.deptno%type
      , p_mgr in emp.mgr%type 
      , p_hired in emp.hiredate%type := sysdate )
is
    invalid_manager exception;
    PRAGMA EXCEPTION_INIT(invalid_manager, -2291);
    dummy varchar2(1);
begin
    -- check hiredate is valid
    if trunc(p_hired) > trunc(sysdate) 
    then
        raise_application_error
            (-20000
             , 'NEW_EMP::hiredate cannot be in the future'); 
    end if;

    insert into emp
        ( ename
          , sal
          , job
          , deptno
          , mgr 
          , hiredate )
    values      
        ( p_name
          , p_sal
          , p_job
          , p_dept
          , p_mgr 
          , trunc(p_hired) );
exception
    when dup_val_on_index then
        raise_application_error
            (-20001
             , 'NEW_EMP::employee called '||p_name||' already exists'
             , true); 
    when invalid_manager then
        raise_application_error
            (-20002
             , 'NEW_EMP::'||p_mgr ||' is not a valid manager'); 

end;
/
Run Code Online (Sandbox Code Playgroud)

看起来如何:

SQL> exec new_emp ('DUGGAN', 2500, 'SALES', 10, 7782, sysdate+1)
BEGIN new_emp ('DUGGAN', 2500, 'SALES', 10, 7782, sysdate+1); END;

*
ERROR at line 1:
ORA-20000: NEW_EMP::hiredate cannot be in the future
ORA-06512: at "APC.NEW_EMP", line 16
ORA-06512: at line 1

SQL>
SQL> exec new_emp ('DUGGAN', 2500, 'SALES', 10, 8888, sysdate)
BEGIN new_emp ('DUGGAN', 2500, 'SALES', 10, 8888, sysdate); END;

*
ERROR at line 1:
ORA-20002: NEW_EMP::8888 is not a valid manager
ORA-06512: at "APC.NEW_EMP", line 42
ORA-06512: at line 1


SQL>
SQL> exec new_emp ('DUGGAN', 2500, 'SALES', 10, 7782, sysdate)

PL/SQL procedure successfully completed.

SQL>
SQL> exec new_emp ('DUGGAN', 2500, 'SALES', 10, 7782, sysdate)
BEGIN new_emp ('DUGGAN', 2500, 'SALES', 10, 7782, sysdate); END;

*
ERROR at line 1:
ORA-20001: NEW_EMP::employee called DUGGAN already exists
ORA-06512: at "APC.NEW_EMP", line 37
ORA-00001: unique constraint (APC.EMP_UK) violated
ORA-06512: at line 1
Run Code Online (Sandbox Code Playgroud)

请注意EXCEPTIONS块中两次调用RAISE_APPLICATION_ERROR的不同输出.将可选的第三个参数设置为TRUE意味着RAISE_APPLICATION_ERROR包括堆栈中的触发异常,这对诊断很有用.

PL/SQL用户指南中有更多有用的信息.


RC.*_*RC. 9

您可以使用RAISE_APPLICATION_ERROR它来创建特定于您的代码/需求的Oracle样式异常/错误.很好地利用这些有助于生成更清晰,更易维护且更易于调试的代码.

例如,如果我有一个应用程序调用存储过程添加用户并且该用户已经存在,那么通常会收到如下错误:

ORA-00001: unique constraint (USERS.PK_USER_KEY) violated
Run Code Online (Sandbox Code Playgroud)

显然,此错误和相关消息并非您尝试执行的任务所独有.通过创建自己的Oracle应用程序错误,您可以更清楚地了解操作的意图和问题的原因.

raise_application_error(-20101, 'User ' || in_user || ' already exists!');
Run Code Online (Sandbox Code Playgroud)

现在,您的应用程序代码可以编写异常处理程序,以便处理此特定错误情况.将其视为一种方法,使Oracle能够以您所定义的"语言"(缺少更好的术语)来传达应用程序所期望的错误条件,并且对应用程序的问题域更有意义.

请注意,用户定义的错误必须介于-20000和-20999之间.

以下链接提供了有关此主题的大量有用信息以及一般的Oracle异常.