亲宝软件园·资讯

展开

Oracle PL/SQL异常处理

springsnow 人气:0

一、异常处理

PL/SQL提供了良好的异常处理机制,当程序运行出现错误时就会触发异常。异常被触发时,程序执行即终止,在PL/SQL块中提供了异常处理的部分,从而可以捕获一个异常进行特殊处理。

1、三种的异常类型:

2、异常的SQLCode 和 SQLERRM

EXCEPTION
WHEN first_exception THEN <code to handle first exception >
WHEN second_exception THEN <code to handle second exception >
WHEN OTHERS THEN <code to handle others exception >
END;

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

二、处理预定义例外

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

常见错误预定义的名称

--例1:更新指定员工工资,如工资小于1500,则加100;
DECLARE
   v_empno employees.employee_id%TYPE := &empno;
   v_sal   employees.salary%TYPE;
BEGIN
   SELECT salary INTO v_sal FROM employees WHERE employee_id = v_empno;
   IF v_sal<=1500 THEN 
        UPDATE employees SET salary = salary + 100 WHERE employee_id=v_empno; 
        DBMS_OUTPUT.PUT_LINE(‘编码为‘||v_empno||‘员工工资已更新!‘);     
   ELSE
        DBMS_OUTPUT.PUT_LINE(‘编码为‘||v_empno||‘员工工资已经超过规定值!‘);
   END IF;
EXCEPTION
   WHEN NO_DATA_FOUND THEN  
      DBMS_OUTPUT.PUT_LINE(‘数据库中没有编码为‘||v_empno||‘的员工‘);
   WHEN TOO_MANY_ROWS THEN
      DBMS_OUTPUT.PUT_LINE(‘程序运行错误!请使用游标‘);
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||‘—‘||SQLERRM);
END;

三、处理非预定义例外(exception_init)

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

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

举例:

--例2:删除指定部门的记录信息,以确保该部门没有员工。
 
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 )

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

<异常情况> EXCEPTION;
RAISE <异常情况>;
--例3:更新指定员工工资,增加100;
 
DECLARE
   v_empno employees.employee_id%TYPE :=&empno;
   no_result  EXCEPTION;-定义异常
BEGIN
   UPDATE employees SET salary = salary+100 WHERE employee_id = v_empno;
   IF SQL%NOTFOUND THEN
      RAISE no_result;//触发异常
   END IF;
EXCEPTION
   WHEN no_result THEN //捕捉异常
      DBMS_OUTPUT.PUT_LINE(‘你的数据更新语句失败了!‘);
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||‘—‘||SQLERRM);

五、应用程序的异常处理。(通过Raise_Application_Error )

调用DBMS_STANDARD(ORACLE提供的包)包所定义的RAISE_APPLICATION_ERROR过程,可以重新定义异常错误消息,它为应用程序提供了一种与ORACLE交互的方法。

RAISE_APPLICATION_ERROR 的语法如下:

RAISE_APPLICATION_ERROR(error_number,error_message,[keep_errors] );

例:创建一个函数get_salary, 该函数检索指定部门的工资总和,其中定义了-20991和-20992号错误,分别处理参数为空和非法部门代码两种错误:

CREATE OR REPLACE FUNCTION get_salary(p_deptno NUMBER) #函数检索指定部门的工资总和
RETURN NUMBER 
AS
  v_sal NUMBER; #函数get_salary返回v_sal值
BEGIN
  IF p_deptno IS NULL THEN
    RAISE_APPLICATION_ERROR(–20991, '部门代码为空'); #用户定义的异常处理
  ELSIF p_deptno<0 THEN
    RAISE_APPLICATION_ERROR(–20992, '无效的部门代码');
  ELSE
    SELECT SUM(employees.salary) INTO v_sal FROM employees 
    WHERE employees.department_id=p_deptno;
    RETURN v_sal;
  END IF;

调用函数

DECLARE 
  V_salary NUMBER(7,2);
  V_sqlcode NUMBER;
  V_sqlerr VARCHAR2(512);
  Null_deptno EXCEPTION;  #定义异常情况
  Invalid_deptno EXCEPTION; #定义异常情况
  PRAGMA EXCEPTION_INIT(null_deptno,–20991);  #非预定义的异常,将它与oracle错误联系起来
  PRAGMA EXCEPTION_INIT(invalid_deptno, –20992); #非预定义的异常,将它与oracle错误联系起来
BEGIN
  BEGIN
    V_salary :=get_salary(–10);
  EXCEPTION
    WHEN invalid_deptno THEN
      V_sqlcode :=SQLCODE;
      V_sqlerr  :=SQLERRM;
      INSERT INTO errlog(errcode, errtext) VALUES(v_sqlcode, v_sqlerr); #将错误SQLCODE及SQLERRM存入到表errlog中  
      COMMIT;
  END ;

例:定义触发器,使用RAISE_APPLICATION_ERROR阻止没有员工姓名的新员式记录插入:

CREATE OR REPLACE TRIGGER tr_insert_emp
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
  IF :new.first_name IS NULL OR :new.last_name is null THEN
    RAISE_APPLICATION_ERROR(–20000,‘Employee must have a name.‘);
  END IF;

到此这篇关于Oracle对PL/SQL异常处理的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。

加载全部内容

相关教程
猜你喜欢
用户评论