1、什么是异常?
答:异常就是程序在运行的时候发生的错误!简称运行时错误。发生异常后,语句停止执行,控制权转移到异常处理部分。
有些异常是可预见的,例如除数不能为零,但有些异常是不可预见的,例如空指针。
一个好的程序应该要有异常处理,即对程序运行时发生的错误进行捕捉和处理。
2、异常分类
异常分为预定义异常,非预定义异常,用户自定义异常。
预定义异常:当PL/SQL程序违反Oracle规则或超越系统限制时隐式引发,有PL/SQL为其声明的预定义名字。eg:no_data_found
如:select ... into ...只能返回一条记录,当返回多条时将导致异常
非预定义异常:当PL/SQL程序违反Oracle规则或超越系统限制时隐式引发,无PL/SQL为其声明的预定义名字。
用户自定义异常:需要用户在程序中定义异常变量,显式地在程序中引发。(用户规定程序不能做什么,如年龄不会大于1000岁)
3、预定义异常语法及使用
begin
过程及SQL语句;
exception
when 异常名称 then
过程及sql语句;
when others then
过程及SQL语句;
end;
使用Oracle数据库的测试用户scott 下的emp表测试:
DECLARE
v_ename emp.ename%TYPE;
BEGIN
SELECT ename INTO v_ename FROM emp
WHERE ename = ‘1111‘;
dbms_output.put_line(‘雇员姓名‘||v_ename);
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line(‘雇员姓名不存在‘);
WHEN OTHERS THEN --发生其他异常
dbms_output.put_line(‘错误号‘||Sqlcode||‘错误名称‘||SQLERRM);
END;
4、非预定义异常语法及使用
非预定义异常比预定义异常多了一个声明部分,即声明异常变量:
declare
<异常情况> exception;
pragma exception_init(<异常情况>,<错误代码>);
begin
过程及SQL语句;
exception
when 异常名称 then
过程及sql语句;
when others then
过程及SQL语句;
end;
预定义异常v_identity 违反主键约束,如员工表的部门编号参照部门表的编号,如果部门表没有部门编号为11这个部门,
这时候员工表将不能更新任何记录的部门编号为11。
DECLARE
v_identity EXCEPTION;
PRAGMA EXCEPTION_INIT(v_identity,-2291);
BEGIN
UPDATE emp SET deptno=‘11‘;
EXCEPTION
WHEN v_identity THEN
dbms_output.put_line(‘部门不存在‘);
END;
5、用户自定义异常语法及使用
declare
temp_ex exception;
begin
raise temp_ex;
exception
when temp_ex then
......
end;
如雇员编号为7369的雇员没有补助,当查询该补助时将会返回空值:
DECLARE
v_comm emp.comm%TYPE;
comm_is_null EXCEPTION;
BEGIN
SELECT comm INTO v_comm FROM emp WHERE empno=7369;
IF v_comm IS NULL THEN
RAISE comm_is_null;
END IF;
dbms_output.put_line(‘雇员补助为:‘||v_comm);
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line(‘没有找到数据‘);
WHEN comm_is_null THEN
dbms_output.put_line(‘该雇员没有补助‘);
WHEN OTHERS THEN
dbms_output.put_line(‘发生其他异常‘);
END;
6、raise_application_error(显示引发异常)
--创建子程序
CREATE OR REPLACE PROCEDURE status(pre_date DATE,act_date DATE)
AS
BEGIN
IF pre_date<act_date THEN --如果预定时间小于实际时间
raise_application_error(-20001,‘已经过期了‘);
END IF;
END;
--调用子程序
DECLARE
time_is_out EXCEPTION;
PRAGMA EXCEPTION_INIT(time_is_out,-20001);
BEGIN
status(to_date(‘2014-9-5‘,‘YYYY-MM-dd‘),to_date(‘2014-9-23‘,‘YYYY-MM-dd‘));
EXCEPTION
WHEN time_is_out THEN
dbms_output.put_line(to_char(SQLERRM(-20001)));
END;