Oracle:PLSQL例外

PLSQL例外

例外,相当于java中的异常,是程序设计语言提供的一种功能,用来增强程序的健壮性和容错性。

有三种类型的异常错误

1、预定义(Predefined)错误

ORACLE预定义的异常情况大约有24个。对这种异常情况的处理,无需在程序中定义,由ORACLE自动将其引发。

2、非预定义(Predefined)错误

即其他标准的ORACLE错误。对这种异常情况的处理,需要用户在程序中定义,然后由ORACLE自动将其引发。

3、用户定义(User_define)错误

程序执行过程中,出现编程人员认为的非正常情况。对这种异常情况的处理,需要用户在程序中定义,然后显式地在程序中将其引发。

预定义的异常处理

对这种异常情况的处理,只需在PL/SQL块的异常处理部分,直接引用相应的异常情况名,并对其完成相应的异常错误处理即可。

WHEN 异常错误信息名称 THEN ...

Oracle:PLSQL例外

--使用oracle系统内置例外,查询100号部门的员工姓名,演示没有找到数据【no_data_found】
declare
    pename varchar2(20);
begin
    select ename into pename from emp where deptno = 100;
    dbms_output.put_line(pename);
exception
    when NO_DATA_FOUND then 
	 dbms_output.put_line('查无该部门员工');
end;
/

非预定义的异常处理

对于这类异常情况的处理,首先必须对非定义的ORACLE错误进行定义。步骤如下:

1、在PL/SQL块的定义部分定义异常情况: 

<异常情况>  EXCEPTION;

2、将其定义好的异常情况,与标准的ORACLE错误联系起来,使用EXCEPTION_INIT语句:

PRAGMA EXCEPTION_INIT(<异常情况>, <错误代码>);

3、在PL/SQL 块的异常情况处理部分对异常情况做出相应的处理:

WHER <异常情况> THEN ...
WHER OTHERS THEN ...
--删除指定部门的记录信息,以确保该部门没有员工。
INSERT INTO departments VALUES(50, ‘FINANCE‘, ‘CHICAGO‘);
DECLARE
   v_deptno departments.department_id%TYPE := &deptno;
   deptno_remaining EXCEPTION;
   PRAGMA EXCEPTION_INIT(deptno_remaining, –2292);
   /* -2292 是违反一致性约束的错误代码 */
BEGIN
   DELETE FROM departments WHERE department_id = v_deptno;
EXCEPTION
   WHEN deptno_remaining THEN 
      DBMS_OUTPUT.PUT_LINE(‘违反数据完整性约束!’);
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||‘—‘||SQLERRM);
END;
/

用户自定义的异常处理

当与一个异常错误相关的错误出现时,就会隐含触发该异常错误。用户定义的异常错误是通过显式使用 RAISE 语句来触发。当引发一个异常错误时,控制就转向到 EXCEPTION块异常错误部分,执行错误处理代码。对于这类异常情况的处理,步骤如下:

1、 在PL/SQL块的定义部分定义异常情况:

<异常情况>  EXCEPTION;

2、在BEGIN节中抛出异常:

RAISE <异常情况>;

3、在PL/SQL 块的异常情况处理部分对异常情况做出相应的处理:

WHER <异常情况> THEN ...
WHER OTHERS THEN ...
--使用用户自定义例外,使用光标cursor,查询10/20/30/100号部门的员工姓名,演示没有找到数据【nohave_emp_found】
declare
	--游标
	cursor cemp(pdeptno number) is select ename from emp where deptno=pdeptno;
	--例外
	nohave_emp_found exception;
	--变量
	pename emp.ename%type;
begin
	--打开游标,这时游标位于第一条记录之前
	open cemp(&xx);
	--向下移动游标一次,指定第一条记录
	fetch cemp into pename;
	--判断
	if cemp%notfound then
		--抛异常
		raise nohave_emp_found;
	else
		--输出变量pename的值
		dbms_output.put_line(pename);
		--循环
		loop
			--向下移动游标一次,指向第二条记录
			fetch cemp into pename;
			--如果找不到记录,就退出
			exit when cemp%notfound;
			--输出变量pename的值
			dbms_output.put_line(pename);
		end loop;
	end if;
	close cemp;
exception
	when nohave_emp_found then
		dbms_output.put_line('查无此部门员工');
end;
/ 

异常处理函数

由于ORACLE 的错信息最大长度是512字节,为了得到完整的错误提示信息,我们可用SQLERRM和SUBSTR 函数一起得到错误提示信息,方便进行错误,特别是如果WHEN OTHERS异常处理器时更为方便。

SQLCODE:返回遇到的Oracle错误号

SQLERRM:返回遇到的Oracle错误信息

WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(SQLCODE||‘——‘||SQLERRM);

--将ORACLE错误代码及其信息存入错误代码表
CREATE TABLE errors (errnum NUMBER(4), errmsg VARCHAR2(100));
DECLARE
   err_msg VARCHAR2(100);
BEGIN
   /*  得到所有 ORACLE 错误信息  */
   FOR err_num IN –100 .. 0 LOOP
      err_msg := SQLERRM(err_num);
      INSERT INTO errors VALUES(err_num, err_msg);
   END LOOP;
END;
/