1.预定义异常
对于系统预定义异常,用户无需在程序中定义,它们将由Oracle自动引发。
1.1如下:如果用户试图使用完全相同的主键值向同一表中插入两条记录,则系统会产生违反主键的异常,Oracle称这种异常为DUP_VAL_ON_INDEX异常.
SQL> set serveroutput on
SQL> begin
2 insert into emp(empno,ename,job,sal,deptno)
3 values(7369,'ATG','CLERK',1500,20);
4 exception
5 when dup_val_on_index then
6 dbms_output.put_line('捕获DUP_VAL_ON_INDEX异常');
7 dbms_output.put_line('该主键值已经存在');
8 end;
9 /
结果:
1.2 在下面的语句中SELECE语句将引发一个异常,该异常将被OTHERS子句捕获。
SQL> set serveroutput on
SQL> declare
2 emp_row emp%rowtype;
3 begin
4 select *
5 into emp_row
6 from emp
7 where deptno=10;
8 exception
9 when others then
10 dbms_output.put_line('异常错误(' || SQLCODE || ')');
11 dbms_output.put_line(SQLERRM);
12 end;
13 /
结果:
2.非预定义异常
SQL> set serveroutput on
SQL> declare
2 fk_delete_exception exception;
3 pragma exception_init(fk_delete_exception,-2292);
4 begin
5 delete dept
6 where dname='SALES';
7 exception
8 when fk_delete_exception then
9 dbms_output.put_line('该项目存在于另一个表中');
10 end;
11 /
结果:
3.用户定义的异常
3.1 在EMP数据表中查找EMPNO=7365的记录,将其值放入变量VAR_SAL中。如果VAR_SAL的值小于800,则说明该员工的薪水有问题,将激活异常处理,显示提示问题。
SQL> set serveroutput on
SQL> declare
2 salary_error exception;
3 var_sal scott.emp.sal%type;
4 begin
5 select sal
6 into var_sal
7 from scott.emp
8 where empno=7369;
9 if var_sal<=800 then
10 raise salary_error;
11 end if;
12 exception
13 when salary_error then
14 dbms_output.put_line('薪金超过范围');
15 end;
16 /
结果:
薪金超过范围
PL/SQL 过程已成功完成。
3.2 用户使用RAISE生成系统处理预定义异常
SQL> set serveroutput on
SQL> declare
2 var_comm number;
3 begin
4 select comm
5 into var_comm
6 from emp
7 where ename='TURNER';
8 if var_comm=0 then
9 raise zero_divide;
10 end if;
11 exception
12 when zero_divide then
13 dbms_output.put_line('补贴费为0!');
14 end;
15 /
结果:
补贴费为0!
PL/SQL 过程已成功完成。