例外处理
1、例外的分类
1)预定义例外:用于处理常见的oracle错误。
2)非预定义例外:用于处理与定义例外不能处理的例外。
3)自定义例外:用于处理与oracle错误无关的其他情况。
2、例外传递
1)编写一个过程,可接收雇员的编号,并显示该雇员的姓名。
- 如果输入的雇员编号不存在,如何处理?
SQL> --例外处理案例 SQL> declare 2 v_ename emp.ename%type; 3 begin 4 select ename into v_ename from emp where empno=&no; 5 dbms_output.put_line('名字:'||v_ename); 6 exception when no_data_found then 7 dbms_output.put_line('编号不存在,请重新输入!'); 8 end; 9 / 编号不存在,请重新输入! PL/SQL procedure successfully completed
3、预定义例外
1)预定义例外
- 由pl/sql所提供的系统例外。
- 当pl/sql应用程序违反了oracle规定的限制时,则会隐含触发一个内部例外。
- pl/sql为开发人员提供了20多个预定义例外。
2)预定义例外case_not_found
- when子句中没有包含必须的条件分支,就会触发case_not_found的例外。
SQL> --case_not_found SQL> create or replace procedure sp_pro11(spno number) is 2 v_sal emp.sal%type; 3 begin 4 select sal into v_sal from emp where empno=spno; 5 case 6 when v_sal<1000 then 7 update emp set sal=sal+100 where empno=spno; 8 when v_sal<2000 then 9 update emp set sal=sal+200 where empno=spno; 10 end case; 11 exception 12 when case_not_found then 13 dbms_output.put_line('case语句没有与'||v_sal||'相匹配的条件'); 14 end; 15 / Procedure created
3)预定义例外cursor_already_open
- 当重新打开已经打开的游标时,会隐含触发例外cursor_already_open。
SQL> --cursor_already_open SQL> declare 2 cursor emp_cursor is select ename,sal from emp; 3 begin 4 open emp_cursor; 5 for emp_reacord1 in emp_cursor loop 6 dbms_output.put_line(emp_record1.ename); 7 end loop; 8 exception 9 when cursor_already_open then 10 dbms_output.put_line('游标已经打开'); 11 end; 12 /
4)预定义例外dup_val_on_index
- 在唯一索引所对应的列上插入重复的值时,会隐含触发例外dup_val_on_index。
SQL> --dup_val_on_index SQL> begin 2 insert into dept values(10,'公关部','北京'); 3 exception 4 when dup_val_on_index then 5 dbms_output.put_line('在deptno列上不能出现重复值'); 6 end; 7 / 在deptno列上不能出现重复值 PL/SQL procedure successfully completed
5)预定义例外invalid_cursor
- 当试图在不合法的有表上执行操作时,会触发该例外。
- 例如:试图从没有打开的游标提取数据,或是关闭没有打开的游标,则会触发该例外。
SQL> --invalid_cursor SQL> declare 2 cursor emp_cursor is select ename,sal from emp; 3 emp_record emp_cursor%rowtype; 4 begin 5 --open emp_cursor;--打开游标 6 fetch emp_cursor into emp_record; 7 dbms_output.put_line(emp_record.ename); 8 close emp_cursor; 9 exception 10 when invalid_cursor then 11 dbms_output.put_line('请检查游标是否打开'); 12 end; 13 / 请检查游标是否打开 PL/SQL procedure successfully completed
6)预定义例外invalid_number
- 当输入的数据有误时,会触发该例外。
- 比如:数字100写成了1oo就会触发该例外。
SQL> --invalid_number SQL> begin 2 update emp set sal=sal+'1oo'; 3 exception 4 when invalid_number then 5 dbms_output.put_line('输入的数字不正确'); 6 end; 7 / 输入的数字不正确 PL/SQL procedure successfully completed
7)预定义例外no_data_found
- 当执行select into没有返回航,就会触发该例外。
--no_data_found declare v_sal emp.sal%type; begin select sal into v_sal from emp where ename= '&name'; exception when no_data_found then dbms_output.put_line( '不存在该员工' ); end;
8)预定义例外too_many_rows
- 执行select into语句时,如果返回超过了一行,则会触发该例外。
SQL> --too_many_rows SQL> declare 2 v_ename emp.ename%type; 3 begin 4 select ename into v_ename from emp; 5 exception when too_many_rows then 6 dbms_output.put_line('返回了多行'); 7 end; 8 / 返回了多行 PL/SQL procedure successfully completed
9)预定义例外zero_divide
- 当执行除法运算时,如果分母为0,则会触发该例外。
10)预定义例外value_error
- 在执行赋值操作时,如果变量的长度不足以容纳实际数据,则会触发该例外value_error。
SQL> --value_error SQL> declare 2 v_ename varchar2(5); 3 begin 4 select ename into v_ename from emp where empno=&no; 5 dbms_output.put_line(v_ename); 6 exception 7 when value_error then 8 dbms_output.put_line('变量长度不够'); 9 end; 10 / 变量长度不够 PL/SQL procedure successfully completed
11)其它预定义例外
- login_denide:用户非法登录。
- not_logged_on:用于未登录就执行dml操作。
- storage_error:超出了内存空间或是内存被损坏。
- timeout_on_resource:oracle在等待资源时,出现超时。
4、非预定义例外
1)非预定义例外:用于处理与与定义例外无关的oracle错误。
- 预定义例外只可以处理21个oracle错误,而当使用pl/sql开发应用程序时,可能会遇到其它的一些oracle错误。比如在pl/sql块中执行dml语句时,违反了约束规定等。在这样的情况下,也可以处理oracle的各种例外。
5、处理自定义例外
- 自定义例外与oracle错误没有任何关联,是由开发人员为特定情况所定义的例外。
- 编写一个pl/sql块,接收一个雇员的编号,并给该雇员工资增加1000元,如果该雇员不存在,请提示。
SQL> --自定义例外 SQL> create or replace procedure ex_test(spNo number) is 2 --定义一个例外 3 myex exception; 4 begin 5 update emp set sal=sal+100 where empno=spNo; 6 --sql%notfound表示没有upadate成功 7 --raise myex;触发myex 8 if sql%notfound then 9 raise myex; 10 end if; 11 exception 12 when myex then 13 dbms_output.put_line('没有更新任何例外'); 14 end; 15 / Procedure created SQL> exec ex_test(56); 没有更新任何例外 PL/SQL procedure successfully completed