快速掌握Oracle异常

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
リリース: 2016-06-07 15:20:30
オリジナル
1324 人が閲覧しました

自定义例外是指由PL/SQL开发人员所定义的例外。预定义例外和非预定义例外都和Oracle错误有关,并且出现Oracle错误时会隐含的处罚相应例外;而自定义例外与Oracle错误没有任何关联,它是由开发人员为特定情况所定义的例外。 看一看以下PL/SQL块的运行。 decla

            自定义例外是指由PL/SQL开发人员所定义的例外。预定义例外和非预定义例外都和Oracle错误有关,并且出现Oracle错误时会隐含的处罚相应例外;而自定义例外与Oracle错误没有任何关联,它是由开发人员为特定情况所定义的例外。

看一看以下PL/SQL块的运行。

1

2

3

4

5

6

7

8

9

declare

    e_integrity exception;

   pragma exception_init(e_integrity,-2291);

begin

    update emp set deptno=&dno where empno=&eno;

exception 

      when e_integrity  then

         dbms_output.put_line('该部门不存在'); 

 end;        

ログイン後にコピー

使用例外函数:

1、SQLCODE 和SQLERRM

  SQLCODE用于返回Oracle错误号,而SQLERRM则用于返回错误号所对应的错误消息。为了在PL/SQL应用程序中处理其他未预料到的Oracle错误,用户可以在例外处理部分的WHEN  OTHERS 子句后引用这两个函数,以取得相关的Oracle错误.示例如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

DECLARE

     v_ename emp.ename%type;

BEGIN

     SELECT ename INTO v_ename

             FROM emp

      WHERE sal=&v_sal;   

   dbms_output.put_line('雇员名:'||v_ename); 

EXCEPTION

    WHEN NO_DATA_FOUND THEN

       dbms_output.put_line('不存在工资为'||&v_sal||'的雇员'); 

    WHEN OTHERS  THEN

       dbms_output.put_line('错误号:'||SQLCODE);

       dbms_output.put_line(SQLERRM); 

 END;     

ログイン後にコピー

当输入v_sal:1250时。

1

2

错误号:-1422

ORA-01422: 实际返回的行数超出请求的行数

ログイン後にコピー


2. RAISE_APPLICATION_ERROR

  该函数用于在PL/SQL应用程序中自定义错误消息。注意该过程只能在数据端的子过程(过程、函数、包、触发器)中使用,而不能在匿名块和客户端的子程序中使用,使用该函数的语法如下:

  raise_application_error(error_number,message[ ,  {TRUE| FALSE}]);

其中,error_number用于定义错误号,该错误号必须是在-20000至-20999之间的负整数;message用于指定错误消息,并且该消息的长度不能超过2048字节;第三个参数为可选参数,如果设置为TURE,则该错误会放在先前错误的堆栈中;如果设置为FALSE(默认值),则会替换先前所有的错误。使用该过程的示例如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

CREATE OR REPLACE PROCEDURE raise_comm

    (eno number,

      commission number

    )

IS

    v_comm  emp.comm%TYPE; 

     

BEGIN

    SELECT comm INTO v_comm

         FROM emp 

      WHERE empno=eno;

  IF v_comm IS NULL THEN

      RAISE_APPLICATION_ERROR(-20021,'该雇员无补助啊',TRUE); 

  END IF;

EXCEPTION

     WHEN NO_DATA_FOUND THEN

       dbms_output.put_line('该雇员不存在');     

END;

ログイン後にコピー


call raise_comm(7900,100);

显示如下错误:

ORA-20021: 该雇员无补助啊
ORA-06512: 在 "SCOTT.RAISE_COMM", line 13

上面出现的错误,会在异常栈中打印出来。

 

 

下面是本人认为比较不错的异常处理方式: 

一般情况下,我们会把异常名和异常号进行绑定,可能就是你所想要的结果吧

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

DECLARE

    vnumber NUMBER(4);

    biger EXCEPTION;           --异常名

    PRAGMA EXCEPTION_INIT(biger,-20001); --异常名和异常号绑定

    equal EXCEPTION;

    PRAGMA EXCEPTION_INIT(equal,-20002);

    small EXCEPTION;

    PRAGMA EXCEPTION_INIT(small,-20003);

BEGIN

    vnumber:=&vnumber;

    IF vnumber >10 THEN

       RAISE_APPLICATION_ERROR(-20001,'哈哈,大于10啊');

    ELSIF vnumber = 10 THEN

       RAISE_APPLICATION_ERROR(-20002,'嗯,等于10...');

   ELSIF vnumber

<p> </p>

<p>除了上面自定义的异常,我们还可以采用下面的这种方式定义异常</p>

<pre class="brush:php;toolbar:false"> CREATE OR REPLACE PROCEDURE pro_emp

 (

   --- 多个用逗号隔开

   v_eno IN NUMBER

 )

 IS

 --------多个用分号隔开

    v_max_id NUMBER;

    v_ename VARCHAR2(10);

    v_raise EXCEPTION;  ---------定义一个异常

BEGIN

      SELECT max(a.empno) into v_max_id  from emp a; 

      IF v_eno >v_max_id  THEN

           RAISE v_raise;               ---遇到例外,执行这个异常,退出程序 进入到Exception部分

      END IF;

      SELECT ename into v_ename from emp where empno=v_eno;

      dbms_output.put_line('员工名称为:'||v_ename);    

EXCEPTION

     WHEN v_raise THEN                                ---------捕获v_raise异常

            dbms_output.put_line('V_ENO大于最大员工号');

        /*  RAISE_APPLICATION_ERROR(-20000,'v_id not exists');    */

     WHEN NO_DATA_FOUND THEN

        /* RAISE_APPLICATION_ERROR(-20011,'ERROR:不存在');*/

          dbms_output.put_line('没有获得有效数据');      

END;

ログイン後にコピー




 

 

 

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート