Oracle中的异常处理与自定义异常方式
目录
- 一、什么是异常处理
- 二、异常的两种分类
- 三、常见的预定义异常
- 四、异常处理语法
- 五、异常常用的三种方案
- 六、使用RAISE_APPLICATION_ERROR创建自定义错误码
- 七、异常练习
- 总结
一、什么是异常处理
程序因为数据的原因或者入参的原因,导致程序出错,这个时候,为了面对这种不可避免的问题,程序块里面添加了异常处理,当程序异常的时候,该怎么办,可以在异常中定义。
二、异常的两种分类
(1) 系统预定义:oracle 自动抛出(如:'违反唯一性约束')
(2) 用户自定义:编码人员认为的 '非正常情况' ( v_exp1 EXCEPTION)
其中 '用户自定义' 的异常在 pl/sql 环境使用,需 '显式抛出'。
三、常见的预定义异常
异常名称 | 错误代码 | 说明 |
---|---|---|
NO_DATA_FOUND | ORA-01403 | 查询无结果 |
TOO_MANY_ROWS | ORA-01422 | 查询返回多行,而 INTO 只接收一行 |
DUP_VAL_ON_INDEX | ORA-00001 | 违反唯一约束 |
ZERO_DIVIDE | ORA-01476 | 除数为零 |
INVALID_NUMBER | ORA-01722 | 字符串转数字失败 |
TIMEOUT_ON_RESOURCE | ORA-00051 | 等待资源超时 |
四、异常处理语法
EXCEPTION WHEN [OTHERS] -- 异常场景 THEN -- 则做的事情
五、异常常用的三种方案
RAISE 异常抛出 --程序不接着往下执行 NULL 忽略异常 ROLLBACK 异常回滚 --程序出现异常则回滚 程序的相关操作(UPDATE/INERT/DELETE)
捕捉异常的关键字是 SQLERRM 它能够得到 异常的详细信息
六、使用RAISE_APPLICATION_ERROR创建自定义错误码
http://www.devze.com自定义异常参数:使用RAISE_APPLICATION_ERROR抛出带自定义错误码和消息的异常。
开发者自定义的错误码,范围为-20000至-20999:
DECLARE v_salary NUMBER := 100000; BEGIN IF v_salary > 50000 THEN RAISE_APPLICATION_ERROR(-20001, '工资超出上限'); -- 自定义错误码 END IF; END;
七、异常练习
declare v_num number := &input; exp_date_range exception; -- 异常定义 bpythonegin if v_num < 0 then raise exp_date_range; -- 异常抛出 end if; dbms_output.put_line(v_num); exception when exp_date_range then dbms_output.put_line('数据范围不能为负数!'); end;
捕捉异常信息:
示例:将EMP表的数据同步到EMP表(把EMP表的数据重复两遍)
create or replace procedure p_16 is begin insert into emp select * from emp; cowww.devze.commmit; exception when others then dbms_output.put_line(SQLERRM); end; BEGIN p_16; end;
示例:入参员工编号,打印对应员工的姓名
程序出现异常之后,忽略使用null;当出现异常的时候,让程序跳出执行 弹出一个报错的框 即抛出异常
create or replace procedure p_17(p_empno number) is v_name varchar2(10); begin select ename into v_name from emp where empno = p_empno; dbms_output.put_line(v_name); exception when others then dbms_output.put_line(SQLERRM); null; raise; -- 弹出窗口 -- rollback;-- 也可以进行回滚 -- 注意:raise语句会重新抛出当前异常,导致后续的 rollback; 永远不会执行 end; BEGIN p_17(p_empno=>1111); end;
程序出现异常,则回滚
下面是一个匿名 PL/SQL 块:
DECLARE dept_no NUMBER(2) := 70; BEGIN --开始事务 INSERT INTO dept VALUES (70, '市场部', '北京'); --插入部门记录 INSERT INTO dept VALUES (70, '后勤部', '上海'); --插入相同编号的部门记录 INSERT INTO emp --插入员工记录 VALUES (7997, '威尔', '销售人员', NULL, TRUNC(SYSDATE), 5000, 300, 70); --提交事务 COMMIT; EXCEPTION WHEN OTHERS THEN --捕捉异常 DBMS_OUTPUT.PUT_LINE(SQLERRM); --显示异常消息 ROLLBACK; --回滚异常 END;
因为dept表的主键插入重复,所nFbRYdVH以捕捉到异常,数据回滚,
插入emp表的语句在插入dept表之后,dept表未插入成功,emp表的编程客栈语句不会跑,因此两张表都插入失败
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。
精彩评论