09-Oracle异常处理
创始人
2024-06-01 02:37:23

本章内容

•异常概述 •异常处理过程 •异常的传播

异常概述

        Oracle错误处理机制

        异常的类型

Oracle错误处理机制

        1、Oracle中对运行时错误的处理采用了异常处理机制。

        2、一个错误对应一个异常,当错误产生时抛出相应的异常,并被异常处理器捕获,程序控制权传递给异常处理器,由异常处理器来处理运行时错误。

异常的类型

•预定义的Oracle异常( Oracle错误) •非预定义的Oracle异常( Oracle错误) •用户定义的异常(用户定义错误)

预定义的Oracle异常

当Oracle错误产生时,与错误对应的预定义异常被自动抛出,通过捕获该异常可以对错误进行处理。 常用预定义异常包括:

异常情况名

错误代码

描述

CURSOR_ALREADY_OPEN

ORA-06511

尝试打开已经打开的游标

INVALID_CURSOR

ORA-01001

不合法的游标操作(如要打开已经关闭的游标)

NO_DATA_FOUND

ORA-01403

没有发现数据

TOO_MANY_ROWS

ORA-01422

一个SELECT  INTO语句匹配多个数据行

INVALID_NUMBER

ORA-01722

转换成数字失败 (‘X’)

VALUE_ERROR

ORA-06502

截断、算法或转换错误,通常出现在赋值错误

ZERO_DIVIDE

ORA-01476

除数为0

ROWTYPE_MISMATCH

ORA-06504

主机游标变量与PL/SQL游标变量类型不匹配

异常情况名

错误代码

描述

DUP_VAL_ON_INDEX

ORA-00001

违反唯一性约束或主键约束

SYS_INVALID_ROWID

ORA-01410

转换成ROWID失败

TIMEOUT_ON_RESOURCE

ORA-00051

在等待资源中出现超时

LOGIN_DENIED

ORA-01017

无效用户名/密码

CASE_NOT_FOUND

ORA-06592

没有匹配的WHEN子句

NOT_LOGGED_ON

ORA-01012

没有与数据库建立连接

STORAGE_ERROR

ORA-06500

PL/SQL内部错误

PROGRAM_ERROR

ORA-06501

PL/SQL内部错误

异常情况名

错误代码

描述

ACCESS_INTO_NULL

ORA-06530

给空对象属性赋值

COLLECTION_IS_NULL

ORA-06531

对某NULL PL/SQL表或可变数组试图应用集合方法,而不是EXISTS

SELF_IS_NULL

ORA-30625

调用空对象实例的方法

SUBSCRIPT_BEYOND_COUNT

ORA-06533

对嵌套表或数组索引引用时超出集合中元素的数量

SUBSCRIPT_OUTSIDE_LIMIT

ORA-06532

对嵌套表或可变数组索引的引用超出声明的范围

非预定义异常

有一些Oracle错误没有预定义异常与其关联,需要在语句块的声明部分声明一个异常名称,然后通过编译指示PRAGMA EXCEPTION_INIT将该异常名称与一个Oracle错误相关联。此后,当执行过程出现该错误时将自动抛出该异常。

•声明一个异常名称 e_integrity EXCEPTION; •将异常与一个Oracle错误号相绑定 PRAGMA EXCEPTION-INIT(e_integrity.-2291) •示例 DECLARE   e_deptno_fk EXCEPTION;   PRAGMA EXCEPTION_INIT(e_deptno_fk,-2292); BEGIN …… EXCEPTION …… END;

用户自定义的异常

用户定义错误是指,有些操作并不会产生Oracle错误,但是从业务规则角度考虑,认为是一种错误。 用户自定义异常必须在声明部分进行声明。 当异常发生时,系统不能自动触发,需要用户使用RAISE语句。 在异常处理部分捕捉并处理异常。

异常处理过程

•异常的定义 •异常的抛出 •异常的捕获与处理 •OTHERS异常处理器

异常处理分3个步骤进行: 在声明部分为错误定义异常,包括非预定义异常和用户定义异常。 在执行过程中当错误产生时抛出与错误对应的异常。 在异常处理部分通过异常处理器捕获异常,并进行异常处理。

异常的定义

•Oracle中的3种异常,其中预定义异常由系统定义,而其他两种异常则需要用户定义。 •定义异常方法 e_exception EXCEPTION; •如果是非预定义的异常,需要将异常与一个Oracle错误相关联,其语法为: PRAGMA EXCEPTION_INIT(e_exception, -#####); •注意 Oracle内部错误号用一个负的5位数表示,如-02292。其中

   -20999~-20000为用户定义错误的保留号。

异常的抛出

•由于系统可以自动识别Oracle内部错误,因此当错误产生时系统会自动抛出与之对应的预定义异常或非预定义异常。但是,系统无法识别用户定义错误,因此当用户定义错误产生时,需要用户手动抛出与之对应的异常。 •用户定义异常的抛出语法为 RAISE user_define_exception;

异常的捕获与处理

•异常处理器的基本形式为 EXCEPTION WHEN exception1[OR excetpion2…]THEN    sequence_of_statements1; WHEN exception3[OR exception4…]THEN    sequence_of_statements2; …… WHEN OTHERS THEN    sequence_of_statementsn; END;
注意: 一个异常处理器可以捕获多个异常,只需在WHEN子句中用

    OR连接即可;

一个异常只能被一个异常处理器捕获,并进行处理。
查询名为SMITH的员工工资,如果该员工不存在,则输出“There is not such an employee!”;如果存在多个同名的员工,则输出其员工号和工资

DECLAREv_sal emp.sal%type;
BEGINSELECT sal INTO v_sal FROM emp WHERE ename='SMITH';DBMS_OUTPUT.PUT_LINE(v_sal);
EXCEPTIONWHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('There is not such an emplyee!');WHEN TOO_MANY_ROWS THENFOR v_emp IN (SELECT * FROM emp WHERE ename='SMITH')    LOOPDBMS_OUTPUT.PUT_LINE(v_emp.empno||' '||v_emp.sal);END LOOP;
END;
删除dept表中部门号为10的部门信息,如果不能删除则输出“There are subrecords in emp table!”。
DECLAREe_deptno_fk EXCEPTION;PRAGMA EXCEPTION_INIT(e_deptno_fk,-2292);
BEGINDELETE FROM dept WHERE deptno=10;
EXCEPTIONWHEN e_deptno_fk THENDBMS_OUTPUT.PUT_LINE(' There are subrecords in emp table!');
END;
修改7844员工的工资,保证修改后工资不超过6000。
DECLAREe_highlimit EXCEPTION;v_sal emp.sal%TYPE;
BEGINUPDATE emp SET sal=sal+100 WHERE empno=7844 RETURNING sal INTO v_sal;IF v_sal>6000 THEN RAISE e_highlimit;END IF;
EXCEPTIONWHEN e_highlimit THENDBMS_OUTPUT.PUT_LINE('The salary is too large!');ROLLBACK;
END; 

OTHERS异常处理器

•OTHERS异常处理器是一个特殊的异常处理器,可以捕获所有的异常。 •通常,OTHERS异常处理器总是作为异常处理部分的最后一个异常处理器,负责处理那些没有被其他异常处理器捕获的异常。

DECLAREv_sal emp.sal%TYPE;e_highlimit EXCEPTION;
BEGINSELECT sal INTO v_sal FROM emp WHERE ename='JOAN';UPDATE emp SET sal=sal+100 WHERE empno=7900;IF v_sal>6000 THEN RAISE e_highlimit;END IF;
EXCEPTIONWHEN e_highlimit THENDBMS_OUTPUT.PUT_LINE('The salary is too large!');ROLLBACK;WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('There is some wrong in selecting!');
END; 
可以通过两个函数来获取错误相关信息。
SQLCODE:返回当前错误代码。 •如果是用户定义错误返回值为1; •如果是ORA-1403:NO DATA FOUND错误,返回值为100 •其他Oracle内部错误返回相应的错误号。 SQLERRM:返回当前错误的消息文本。 •如果是Oracle内部错误,返回系统内部的错误描述; •如果是用户定义错误,则返回信息文本为“User-defined Exception”。
DECLAREv_sal emp.sal%TYPE;e_highlimit EXCEPTION;v_code NUMBER(6);v_text VARCHAR2(200);
BEGINSELECT sal INTO v_sal FROM emp WHERE ename='JOAN';UPDATE emp SET sal=sal+100 WHERE empno=7900;IF v_sal>6000 THEN RAISE e_highlimit;END IF;
EXCEPTIONWHEN e_highlimit THENDBMS_OUTPUT.PUT_LINE('The salary is too large!');ROLLBACK;WHEN OTHERS THENv_code:=SQLCODE;v_text:=SQLERRM;   DBMS_OUTPUT.PUT_LINE(v_code||' '||v_text);
END; 

异常的传播

•执行部分的异常 •声明部分和异常处理部分的异常

执行部分异常的传播

•如果当前语句块有该异常的处理器,则执行之,并且成功完成该语句块。然后,控制权传递到外层语句块。 •如果当前语句块没有该异常的处理器,则通过在外层语句块中产生该异常来传播该异常。然后,执行对外层语句块执行步骤1。如果没有外层语句块,则该异常将传播到调用环境。

DECLAREv_sal emp.sal%TYPE;
BEGINBEGIN  SELECT sal INTO v_sal FROM emp WHERE ename='JOAN';EXCEPTIONWHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('There is not such an employee!');END;DBMS_OUTPUT.PUT_LINE('Now this is outputted by outer block!');
END;
/
There is not such an employee!
Now this is outputted by outer block! 
DECLAREv_sal emp.sal%TYPE;
BEGINBEGIN  SELECT sal INTO v_sal FROM emp WHERE deptno=10;EXCEPTIONWHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('There is not such an employee!');END;DBMS_OUTPUT.PUT_LINE('Now this is outputted by outer block!');
EXCEPTIONWHEN TOO_MANY_ROWS THENDBMS_OUTPUT.PUT_LINE('There are more than one employee!');
END;
/
There are more than one employee!

声明部分和异常处理部分的异常

        声明部分和异常处理部分的异常会立刻传播到外层语句块的异常处理部分,即使当前语句块有该异常的异常处理器。

BEGINDECLARE
v_number NUMBER(6) :='ABC';
BEGINv_number:=10;EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('This is outputted by inner         block!');END;
EXCEPTION
WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('This is outputted by outer block!');
END;
/
This is outputted by outer block! 

结论

无论是执行部分的异常,还是声明部分或异常处理部分的异常,如果在本块中没有处理,最终都将向外层块中传播。 通常在程序最外层块的异常处理部分放置OTHERS异常处理器,以保证没有错误被漏掉检测,否则错误将传递到调用环境。

        本人从事软件项目开发20多年,2005年开始从事Java工程师系列课程的教学工作,录制50多门精品视频课程,包含java基础,jspweb开发,SSH,SSM,SpringBoot,SpringCloud,人工智能,在线支付等众多商业项目,每门课程都包含有项目实战,上课PPT,及完整的源代码下载,有兴趣的朋友可以看看我的在线课堂

讲师课堂链接:https://edu.csdn.net/lecturer/893

相关内容

热门资讯

苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
阿西吧是什么意思 阿西吧相当于... 即使你没有受到过任何外语培训,你也懂四国语言。汉语:你好英语:Shit韩语:阿西吧(아,씨발! )日...