异常处理的语句 begin 执行语句; exception when 异常错误信息名称 then 异常处理方法; when 异常错误信息名称 then 异常处理方法; whenothersthen 异常处理方法; end;
1.预定义异常
有错误编码,也有错误名称
例:返回多条数据的错误
1 2 3 4 5 6 7
declare v_emp emp%rowtype; begin select * into v_emp from emp;--错误原因:返回内容超出一条 dbms_output.put_line(v_emp.empno); exception when too_many_rows then dbms_output.put_line('返回内容超出一条'); end;
例:输入值超出范围的错误 输入一个员工编号,正确的话打印姓名,错误的话打印’查无此人’
1 2 3 4 5 6 7
declare v_emp emp%rowtype; begin select ename into v_emp.ename from emp where empno=&员工编号; dbms_output.put_line(v_emp.ename); exception when no_data_found then dbms_output.put_line('查无此人'); end;
declare v_emp emp%rowtype; begin select * into v_emp from emp where deptno = &部门编号; dbms_output.put_line(v_emp.ename || ' ' || v_emp.sal); exception when no_data_found then dbms_output.put_line('该部门不存在'); when too_many_rows then dbms_output.put_line('该部门员工人数过多'); end;
2.非预定义异常
有错误编码,没有错误名称 想要使用必须自己定义错误名称,和错误编码进行绑定
使用非预定义异常的三个步骤
在程序块中的声明部分定义一个异常名称
在声明部分使用函数将异常名称和错误编码关联 —– pragma 编译指示 init 初始化
在异常处理部分捕获异常并使用
例:删除掉dept表中的20号部门,如果该部门有员工存在,则返回’不能删,该部门还有喘气的’
1 2 3 4 5 6 7 8 9
delete from dept where deptno = 20;
declare in_fk exception;---定义一个异常名称 pragma exception_init(in_fk,-02292);--关联异常名称 begin delete from dept where deptno = 20; exception when in_fk then dbms_output.put_line('不能删,该部门还有喘气的'); end;
例:返回多条数据的错误 –(可不可以用非预定义异常来写?)
1 2 3 4 5 6 7 8 9 10
DECLARE IN_FK EXCEPTION; PRAGMA EXCEPTION_INIT(IN_FK, -01422); A EMP%ROWTYPE; BEGIN SELECT * INTO A FROM EMP; EXCEPTION WHEN IN_FK THEN DBMS_OUTPUT.PUT_LINE('太多啦太多啦'); when too_many_rows then dbms_output.put_line('该部门员工人数过多');--冗余异常,同种异常给了两个解决方法 END;
3.自定义异常
需要手动引发异常,通常用于不会报错的场景,不需要错误编号跟错误名称,只需要声明异常名称
raise 异常名称 –引发异常的关键词
语法结构 declare 异常名称 exception; begin 执行程序; raise 异常名称; —–通常放在if语句中判断 exceptionwhen 异常名称 then 处理方法; end;
declare v_emp emp%rowtype; xinziyichang exception; begin select * into v_emp from emp where ename = '&员工姓名'; if v_emp.sal < 3000 then raise xinziyichang; end if; dbms_output.put_line(v_emp.sal); exception when xinziyichang then dbms_output.put_line('给老子涨薪'); when no_data_found then dbms_output.put_line('已经提桶跑路'); end;
declare v_no number := &数值; xinxiyouwu exception; v_dept dept%rowtype; v_emp emp%rowtype; begin if v_no = 1 then for v_dept in (select * from dept) loop dbms_output.put_line(v_dept.dname); end loop; elsif v_no = 2 then for v_emp in (select * from emp) loop dbms_output.put_line(v_emp.ename); end loop; else raise xinxiyouwu; end if; exception when xinxiyouwu then dbms_output.put_line('您输入的信息不合法,请输入1或2'); end;
declare cursor cur1 is select * from dept; cursor cur2 is select * from emp; a number:=&参数; yichang exception; begin if a=1 then for i in cur1 LOOP dbms_output.put_line(i.dname); end loop; elsif a=2 THEN for i in cur2 LOOP dbms_output.put_line(i.empno); end loop; else raise yichang; end if; exception when yichang then dbms_output.put_line('您输入的信息不合法,请输入1或2'); END;