1. 预定义 ( Predefined )错误
ORACLE预定义的异常情况大约有24个。对这种异常情况的处理,无需在程序中定义,由ORACLE自动将其引发。
2. 非预定义 ( Predefined )错误
即其他标准的ORACLE错误。对这种异常情况的处理,需要用户在程序中定义,然后由ORACLE自动将其引发。
3. 用户定义(User_define) 错误
程序执行过程中,出现编程人员认为的非正常情况。对这种异常情况的处理,需要用户在程序中定义,然后显式地在程序中将其引发。
3、异常的结构
EXCEPTION
WHEN exception1 [OR exception2 . . .] THEN
statement1;
statement2;
. . .
[WHEN exception3 [OR exception4 . . .] THEN
statement1;
statement2;
. . .]
[WHEN OTHERS THEN
statement1;
statement2;
. . .] --在异常部分WHEN 子句没有数量限制
--WHEN OTHERS 是最后一个子句
--异常处理部分从关键字EXCEPTION开始
--当异常抛出后,控制无条件转到异常处理部分
--在离开块之前只能执行一种异常处理
4、异常类型
4.1 预定义异常
在相应的异常处理例程中引用错误的标准名来截获一个Oracle 服务器预定义错误。
DECLARE
test varchar(10);
BEGIN
SELECT DNAME INTO test FROM DEPT WHERE DEPTNO='';
DBMS_OUTPUT.PUT_LINE(test);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('没有找到符合条件的数据');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('返回的数据行过多');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('EORROR:'||SQLCODE||'-'||SQLERRM);
END;
4.2 非预定义异常
1. 在声明部分声明异常名。
语法:
exception EXCEPTION;
其中: exception 异常名
2. 使用PRAGMAEXCEPTION_INIT语句将异常处理名字和Oracle的错误代码关联起来.
语法:
PRAGMA EXCEPTION_INIT ( exception, error_number ) ;
其中: exception 先前声明的异常名
error_number 标准Oracle 错误代码
3. 在相应的异常处理例程中引用已声明的异常。
关键字 PRAGMA (伪指令pseudoinstructions)表示语句是一个编译指令,在执行PL/SQL块时并不处理该语句。在PL/SQL块中,一个编译指令EXCEPTION_INIT告诉编译器将一个异常处理的名字和一个Oracle错误代码联系起来。
DECLARE
e_emp_cons EXCEPTION;
PRAGMA EXCEPTION_INIT(e_emp_cons,-00001);
BEGIN
INSERT INTO emp
SELECT * FROM emp;
EXCEPTION
WHEN e_emp_cons THEN
dbms_output.put_line('违反唯一性约束');
END;
4.3 自定义异常
在PL/SQL块的声明部分声明
使用RAISE语句显式地发布
DECLARE
name varchar(10);
ex EXCEPTION; --定义异常ex
BEGIN
SELECT DNAME INTO name FROM DEPT WHERE DEPTNO='';
DBMS_OUTPUT.PUT_LINE(name);
IF NAME<>'HR' THEN
RAISE ex; --触发异常
END IF;
EXCEPTION
WHEN ex THEN
DBMS_OUTPUT.PUT_LINE('10号部门不是HR'); --处理异常
END;
4、异常的传递
当子块自己处理异常时,它可以正常终止,并且在子块的END语句之后可以立即将控制交给外部块。
然而,如果 PL/SQL出现了异常,但当前块中没有针对该异常的处理机,就会寻找外部块中有没有处理机,如果所有的外部块都不能处理这个异常,则就会在宿主环境中出现未经处理的异常。
当把异常传播给外部块,则当前块中的等待执行代码都不再被执行。
这种方法的优点就是内部块仅处理自己特有的错误,而将一般的异常处理留给外部块。