Oracle学习--->6、异常处理机制
1、Oracle中的错误分为两大类:
- 编译时错误:程序在编写过程中出现的错误
- 运行时错误:程序在运行过程中因为各种原因产生 的运行时错误
2、异常处理语法,基本处理结构包含3个部分:
- 在定义区,定义异常,如果使用预定义异常,则不用再定义区定义异常
- 在执行区,可以显示地出发异常,也可以有PL/SQL引擎触发异常
- 只要在执行过程中出现了异常,那么执行区中后续的语句将立即停止执行,语句执行流程跳转到异常处理区
3、注意点:
- 当RAISE语句触发异常后,程序的执行流程将跳转到EXCEPTION部分的异常处理类型异常处理块中。
- 在EXCEPTION语句块中,使用多个WHEN THEN语句来捕捉多个异常,对于未处理的异常,可以使用WHEN OTHERS THEN来提供一个统一的异常处理
异常处理结构示例
DECLARE e_duplicate_name EXCEPTION; emp_id EMPLOYEER.EMPLOYEER_ID%TYPE; emp_new_id EMPLOYEER.EMPLOYEER_ID%TYPE := '700001'; BEGIN SELECT employeer_id INTO emp_id FROM employeer WHERE employeer_id = '800001'; IF emp_id = emp_new_id THEN RAISE e_duplicate_name; END IF; INSERT INTO employeer VALUES ('10', emp_new_id, 'aaaaa', 'aaaa',SYSDATE); EXCEPTION WHEN e_duplicate_name THEN DBMS_OUTPUT.put_line ('不能插入重复的工号'); WHEN OTHERS THEN DBMS_OUTPUT.put_line ( '异常编码:' || SQLCODE || ' , 异常信息:' || SQLERRM); END;
不能插入重复的工号
异常编码:-1722 , 异常信息:ORA-01722: 无效数字
SQLCODE:数据库操作的返回码
SQLERRM是一则函数。oracle sqlerrm函数 sqlerrm函数返回指定错误代码的错误信息。
4、预定义异常:
预定义异常的使用,只需将异常名称放在WHEN子句后面即可,使用时只需要使用它的异常名称即可
DECLARE v_temp VARCHAR2 (10); BEGIN v_temp := 'abcdefghijklmn'; EXCEPTION WHEN VALUE_ERROR THEN DBMS_OUTPUT.put_line ('出现VALUE_ERROR错误,错误编码为:' || SQLCODE || ' , 错误名称:' || SQLERRM); END;
出现VALUE_ERROR错误,错误编码为:-6502 , 错误名称:ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太
5、自定义异常:
- 5.1、声明异常
-
DECLARE e_duplicate_name EXCEPTION; --自定义异常 BEGIN NULL; END
- 5.2、作用域范围
- ①、在同一个块中不能声明一个异常超过两次,但是可以在不同的块中声明相同的异常
- ②、在一个块中声明的异常在本块中和其子块中可见,也就是说在内存块可以引用在外层块中定义的异常,可以引用在本地中定义的异常,但不能引用在子块中定义的异常
-
DECLARE e_duplicate_name EXCEPTION; --定义外层块异常 BEGIN DECLARE e_duplicate_name EXCEPTION; --覆盖了外层块中的异常 BEGIN RAISE e_duplicate_name; --触发内存块中的异常 END; EXCEPTION WHEN e_duplicate_name --此时并不能捕捉获取改异常 THEN DBMS_OUTPUT.put_line ('出现错误,错误编码为:' || SQLCODE || ' , 错误名称:' || SQLERRM); --显示错误编码和错误消息 WHEN OTHERS THEN --以其他异常被传递 NULL; END;
- 5.3、使用RASIE_APPLICATION_ERROR
- RASIE_APPLICATION_ERROR在子程序内部使用时,能够帮助用户从存储子程序中抛出用户自定义的错误消息
- 语法:RASIE_APPLICATION_ERROR(error_number, error_message, [keep_errors]);
- error_number:范围在-20000到-20999之间的负数
- error_message:是最大长度为2048字节的字符串
- keep_error:是一个可选的布尔值,当值为True,新的错误将被添加到已经抛出的错误列表中,默认值为False,将新的错误代替当前的错误列表
- 注意:RASIE_APPLICATION_ERROR只能在存储的子程序中调用,当被调用时,将结束当前的子程序并返回一个用户自定义的错误代码和错误消息给应用程序,这些错误代码和错误消息可以被任何Oracle错误一样被捕捉
-
CREATE OR REPLACE PROCEDURE REGISTEREMPLOYEER ( p_deaprt_id IN EMPLOYEER.DEPARTMENT_ID%TYPE, p_emp_id IN EMPLOYEER.EMPLOYEER_ID%TYPE, p_emp_name IN EMPLOYEER.EMPLOYEER_NAME%TYPE, p_emp_saylary IN EMPLOYEER.EMPLOYEER_SALARY%TYPE) AS v_num NUMBER; BEGIN IF p_emp_id IS NULL --如果工号为NULL则触发错误 THEN raise_application_error (-20000, '员工编号不能为空'); --触发应用程序异常 ELSE SELECT COUNT (*) INTO v_num FROM employeer WHERE employeer_id = p_emp_id; IF v_num > 0 THEN raise_application_error (-20000, '员工编号为:' || p_emp_id || '的员工工号已经存在'); --触发应用程序异常 END IF; END IF; INSERT INTO employeer VALUES (p_deaprt_id, p_emp_id, p_emp_name, p_emp_saylary, SYSDATE); EXCEPTION WHEN OTHERS --捕捉应用程序异常 THEN raise_application_error (-20003,'插入数据是出现错误。异常编码为:'|| SQLCODE || '异常描述' || SQLERRM); END;
- 5.4、抛出异常
- Oracle显式地使用RAISE语句抛出异常
- 语法:RAISE exception_name
- 5.5、处理异常
- 当异常被触发,控制将转到语句块异常处理区
- 语法: EXCEPTION WHEN exception_name THEN
-
DECLARE e_nocomm EXCEPTION; v_comm NUMBER; v_empno NUMBER := &empno; BEGIN SELECT employeer_salary INTO v_comm FROM employeer WHERE employeer_id = v_empno; IF v_comm < 0 THEN RAISE e_nocomm; END IF; EXCEPTION WHEN e_nocomm THEN DBMS_OUTPUT.PUT_LINE ('员工的工资不正确'); WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE ('没有找到任何数据'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE ('其他未处理的异常'); END;
NO_DATA_FOUND表示查询的数据为空,可以专门处理这种业务
- 一个处理器中处理多个异常
-
DECLARE e_nocomm EXCEPTION; v_comm NUMBER; v_empno NUMBER := &empno; BEGIN SELECT employeer_salary INTO v_comm FROM employeer WHERE employeer_id = v_empno; IF v_comm < 0 THEN RAISE e_nocomm; END IF; EXCEPTION WHEN e_nocomm OR NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE ('员工的工资出现异常'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE ('其他未处理的异常'); END;
6、异常的传递
异常传递是指当异常被抛出时,执行立即跳转到EXCEPTION语句块中的异常处理器,在异常处理器中查找是否有匹配的异常,如果在当前的PL/SQL块或子程序中没有找到对应的异常处理器,
那么这个异常会向其PL/SQL块外层或子程序的调用方传递,知道没有可以搜索到的块为止,这里PL/SQL引擎抛出一个未处理的异常
- 6.1、执行时异常传递
- 执行时异常传递是指在PL/SQL块的执行部分抛出异常的传递机制,当在执行部分抛出异常后,PL/SQL使用下面的机制来确定使用哪一种处理器
- 6.2、声明时异常传递
- 6.3、异常处理器中的异常
- 6.4、重新抛出异常
- 6.5、异常处理准则
posted on 2016-11-22 09:48 LiGengMing 阅读(775) 评论(0) 编辑 收藏 举报