重庆思庄Oracle、Redhat认证学习论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3113|回复: 2
打印 上一主题 下一主题

PL/SQL 非预定义异常、自定义异常处理、RAISE_APPLICATION_ERROR

[复制链接]
跳转到指定楼层
楼主
发表于 2014-3-21 17:31:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

抛出异常

Oracle有三种类型的异常错误:

1. 预定义(Predefined)异常


ORACLE预定义的异常情况大约有24个。对这种异常情况的处理,无需在程序中定义,由ORACLE自动将其引发。


2. 非预定义(Predefined)异常


即其他标准的ORACLE错误。对这种异常情况的处理,需要用户在程序中定义,然后由ORACLE自动将其引发。


3. 用户定义(User_define)异常


程序执行过程中,出现编程人员认为的非正常情况。对这种异常情况的处理,需要用户在程序中定义,然后显式地在程序中将其引发。


在PL/SQL中有三种方式抛出异常

通过PL/SQL运行时引擎——抛出Oracle异常


使用RAISE语句——抛出用户定义异常


调用RAISE_APPLICATION_ERROR存储过程——抛出用户定义异常



非预定义异常

因为非预定义异常只有编号,没有名称,所以不能直接处理。

1、在PL/SQL 块的定义部分定义异常情况:


 <异常情况>  EXCEPTION; 


2、将其定义好的异常情况,与标准的ORACLE错误联系起来,使用EXCEPTION_INIT语句:


PRAGMA EXCEPTION_INIT(<异常情况>, <错误代码>);


3、在PL/SQL 块的异常情况处理部分对异常情况做出相应的处理。

INSERT INTO departments VALUES(50, 'FINANCE', 'CHICAGO');  

  

DECLARE  

   v_deptno departments.department_id%TYPE := &deptno;  

   deptno_remaining EXCEPTION;                     --1、定义异常  

   PRAGMA EXCEPTION_INIT(deptno_remaining, -2292); --2、关联  

   -- -2292 是违反一致性约束的错误代码   

BEGIN  

   DELETE FROM departments WHERE department_id = v_deptno;  

EXCEPTION  

   WHEN deptno_remaining THEN                      --3、处理  

      DBMS_OUTPUT.PUT_LINE('违反数据完整性约束!');  

   WHEN OTHERS THEN  

      DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);  

END;  


用户自定义异常处理

用户定义的异常错误是通过显式使用 RAISE 语句来触发。


1、在PL/SQL 块的定义部分定义异常情况 ;


2、RAISE <异常情况>;


3、在PL/SQL 块的异常情况处理部分对异常情况做出相应的处理。


DECLARE  

   v_empno employees.employee_id%TYPE :=&empno;  

   no_result  EXCEPTION;              --1、定义  

BEGIN  

   UPDATE employees SET salary = salary+100 WHERE employee_id = v_empno;  

   IF SQL%NOTFOUND THEN  

      RAISE no_result;                --2、抛出  

   END IF;  

EXCEPTION  

   WHEN no_result THEN                --3、处理  

      DBMS_OUTPUT.PUT_LINE('你的数据更新语句失败了!');  

   WHEN OTHERS THEN  

      DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);  

END;  



RAISE_APPLICATION_ERROR

调用DBMS_STANDARD(ORACLE提供的包)包所定义的RAISE_APPLICATION_ERROR过程,可以重新定义异常错误消息,将应用程序专有的错误从服务器端转达到客户端应用程序。它为应用程序提供了一种与ORACLE交互的方法。



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 支持支持 反对反对
回复

使用道具 举报

沙发
 楼主| 发表于 2014-3-21 17:31:49 | 只看该作者

语法如下:


     RAISE_APPLICATION_ERROR(error_number, error_message, [keep_errors] );


error_number 是从 –20,000 到 –20,999 之间的参数,这样就不会与 ORACLE 的任何错误代码发生冲突

error_message 是相应的提示信息(< 2048 字节),

keep_errors 为可选,如果keep_errors =TRUE ,则新错误将被添加到已经引发的错误列表中。如果keep_errors=FALSE(缺省),则新错误将替换当前的错误列表。

There are two uses for RAISE_APPLICATION_ERROR. 

The first is to replace generic Oracle exception messages with our own, more meaningful messages. 

The second is to create exception conditions of our own, when Oracle would not throw them.

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;                     --1、定义  

    PRAGMA EXCEPTION_INIT(invalid_manager, -2291); --2、关联  

    dummy varchar2(1);  

begin  

    if trunc(p_hired) > trunc(sysdate)   

    then  

        raise_application_error  

           (-20000, 'NEW_EMP::hiredate cannot be in the future'); --3、抛出自定义异常  

    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); --3、包装Oracle异常  

    when invalid_manager then  

        raise_application_error  

            (-20002, 'NEW_EMP::'||p_mgr ||' is not a valid manager'); --3、包装自定义异常  

  

end;  

/  


客户端调用时会提示详细异常信息:

-- 测试RAISE_APPLICATION_ERROR自定义异常  

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-20000  

ORA-06512: at "APC.NEW_EMP", line 16  

ORA-06512: at line 1  

  

-- 测试RAISE_APPLICATION_ERROR包装自定义异常  

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  

  

  


回复 支持 反对

使用道具 举报

板凳
 楼主| 发表于 2014-3-21 17:32:01 | 只看该作者

-- 测试RAISE_APPLICATION_ERROR包装Oracle异常  

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  

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|重庆思庄Oracle、Redhat认证学习论坛 ( 渝ICP备12004239号-4 )

GMT+8, 2024-5-15 08:03 , Processed in 0.094510 second(s), 20 queries .

重庆思庄学习中心论坛-重庆思庄科技有限公司论坛

© 2001-2020

快速回复 返回顶部 返回列表