PLSQL中的例外处理
PLSQL中的例外一般有两种:
1、Oracle 内部错误抛出的例外:这又分为预定义例外(有错误号+常量定义)和 非预定义例外 (仅有错误号,无常量定义)
2、程序员显式的抛出的例外
1、内部错误抛出的例外
A.预定义例外(有错误号+常量定义)
B.非预定义例外(仅有错误号,无常量定义)
2、显式的抛出的例外
3、PLSQL中的例外处理的一般语法
EXCEPTIONWHEN exception1 [OR exception2 . . .] THENstatement1;statement2;. . .[WHEN exception3 [OR exception4 . . .] THENstatement1;statement2;. . .][WHEN OTHERS THENstatement1;statement2;. . .]
A.PLSQL定义的常见例外
Oracle 预定义好的常见例外:
–NO_DATA_FOUND
–TOO_MANY_ROWS
–INVALID_CURSOR
–ZERO_DIVIDE
–DUP_VAL_ON_INDEX
处理预定义的例外:有些常见例外,Oracle 都已经预定义好了,使用时无需预先声明,比如: NO_DATA_FOUND 和 TOO_MANY_ROWS 是最常见的例外
BEGIN. . .EXCEPTIONWHEN NO_DATA_FOUND THENstatement1;WHEN TOO_MANY_ROWS THENstatement1;WHEN OTHERS THENstatement1;statement2;END;
B.OTHERS的处理
Others表明程序员未能预计到这种错误,所以全部归入到others 里面去了
4、Oracle 错误号和错误描述
Oracle 提供了两个内置函数 SQLCODE 和 SQLERRM 分别用来返回Oracle 错误号和错误描述
DECLAREv_error_code NUMBER;v_error_message VARCHAR2(255);BEGIN...EXCEPTION...WHEN OTHERS THENROLLBACK;v_error_code := SQLCODE ;v_error_message := SQLERRM ;INSERT INTO errorsVALUES(v_error_code, v_error_message);END;
5、处理非预定义的Oracle错误
此类错误属于Oracle错误,有编号,但无错误名称定义,使用时需要先声明,并 进行错误初始化
DEFINE p_deptno = 10DECLAREe_emps_remaining EXCEPTION;PRAGMA EXCEPTION_INIT(e_emps_remaining, -2292);BEGINDELETE FROM departmentsWHERE department_id = &p_deptno;COMMIT;EXCEPTIONWHEN e_emps_remaining THENDBMS_OUTPUT.PUT_LINE ('Cannot remove dept ' ||TO_CHAR(&p_deptno) || '. Employees exist. ');END;
6、处理用户自定义的错误
这种错误一般是程序员根据具体的业务逻辑定义的应用类错误,需要先声明后使用: 定义和处理过程如下
DECLAREe_invalid_department EXCEPTION;BEGINUPDATE departmentsSET department_name = &p_department_descWHERE department_id = &p_department_number;IF SQL%NOTFOUND THENRAISE e_invalid_department;END IF;COMMIT;EXCEPTIONWHEN e_invalid_department THENDBMS_OUTPUT.PUT_LINE('No such department id.');END;
7、RAISE_APPLICATION_ERROR() 函数
对于用户自定义的业务错误,如果觉得先定义再使用很麻烦,那么 也可以简单的使用raise_application_error() 来简化处理。它可以无需预先定义错误,而在需要抛出错误的 地方直接使用此函数抛出例外,例外可以包含用户自定义的错误码和错误描述
BEGIN...DELETE FROM employeesWHERE manager_id = v_mgr;IF SQL%NOTFOUND THENRAISE_APPLICATION_ERROR(-20202,'This is not a valid manager');END IF;......EXCEPTIONWHEN NO_DATA_FOUND THENRAISE_APPLICATION_ERROR (-20201,'Manager is not a valid employee.');END;
8、例外传递
当前块中不处理,传递到外层
DECLARE. . .e_no_rows exception;e_integrity exception;PRAGMA EXCEPTION_INIT (e_integrity, -2292);BEGINFOR c_record IN emp_cursor LOOPBEGINSELECT ...UPDATE ...IF SQL%NOTFOUND THENRAISE e_no_rows;END IF;END;END LOOP;EXCEPTIONWHEN e_integrity THEN ...WHEN e_no_rows THEN ...END;
