ORACLE学习之PL/SQL编程——异常处理

目录

  • 阅读准备事项
  • 异常简介
  • 捕捉并处理异常
    1. 预定义异常
    2. 非预定义异常
    3. 自定义异常
  • 使用异常处理函数
  • 使用编译警告

阅读准备事项

  添加外键关联:

ALTER TABLE dept_learn ADD CONSTRAINT pk_dept_deptid PRIMARY KEY (department_id); 
ALTER TABLE emp_learn ADD CONSTRAINT fk_emp_dept_deptid FOREIGN KEY (department_id) REFERENCES dept_learn(department_id);

异常简介

    在PL/SQL块中捕获并处理异常,可以提高程序的健壮性,使得应用程序可以安全正常的运行。异常是一种PL/SQL标识符,它有预定义异常、非预定义异常和自定义异常三种类型。在PL/SQL块中,如果不捕获和处理异常,oracle会将错误传递到调用环境。

     本节学习目标:

  • 学会使用上面介绍的3种异常。
  • 学会使用异常处理函数。
  • 学会使用PL/SQL编译警告。   

  异常使用语法:

  DECLARE statements;

  BEGIN

    statements;

  EXCEPTION

    WHEN exception1 [OR exception2 ...] THEN

       statements;

    [WHEN exception3 [OR exception4 ...] THEN

       statements;]

    [WHEN OTHERS THEN

       statements;]

  END;

捕捉并处理异常

  • 预定义异常

    指由PL/SQL所提供的系统异常。oracle为开发人员提供了21个预定义异常(将在本节末尾一一列出),每个预定义异常对应一个特定的oracle错误,当PL/SQL块出现这些oracle错误时,会隐含的触发相应的预定义异常。

   示例:

 1 DECLARE
 2    v_name emp_learn.first_name%TYPE;
 3 BEGIN
 4    SELECT first_name INTO v_name FROM emp_learn WHERE department_id = &dno;
 5    dbms_output.put_line('雇员号'||&dno||'的名字为:'||v_name);
 6 EXCEPTION
 7    WHEN NO_DATA_FOUND THEN
 8       dbms_output.put_line('不存在该部门!');
 9    WHEN TOO_MANY_ROWS THEN
10       dbms_output.put_line('该部门有多个员工!');
11    WHEN OTHERS THEN
12       dbms_output.put_line('未知错误!');
13 END;
处理NO_DATE_FOUND和TOO_MANY_ROWS预定义异常
  • 非预定义异常

   非预定义异常用于处理与预定义异常无关的oracle错误。预定义异常只能处理21种oracle错误,而PL/SQL块可能还会遭遇其它oracle错误,此时可能需要用到非预定义异常了。  非预定义异常使用步骤:

  a)定义异常标识符。必须在定义部分定义异常标识符。

  b)在oracle错误号和异常之间建立关联。需要在定义部分引用伪过程EXCEPTION_INIT。

  c)捕捉并处理异常。

  示例:在此节的开始时,我们为emp_learn和dept_learn变建立了外键关联,当更新雇员的部门号时,部门号必须在dept_learn表中存在,否则会触发ORA-02291错误。

SQL> UPDATE emp_learn SET department_id=2000 WHERE employee_id = 198;
ORA-02291: 违反完整约束条件 (HR.FK_EMP_DEPT_DEPTID) - 未找到父项关键字
触发ORA-02291错误
 1 DECLARE
 2    e_int EXCEPTION;
 3    PRAGMA EXCEPTION_INIT(e_int,-2291);
 4    v_name emp_learn.first_name%TYPE:=LOWER('&name');
 5    v_deptno dept_learn.department_id%TYPE:=&dno;    
 6 BEGIN
 7    UPDATE emp_learn SET department_id=v_deptno WHERE LOWER(first_name) = v_name;
 8 EXCEPTION
 9    WHEN e_int THEN
10       dbms_output.put_line('该部门不存在!');
11 END;
使用非预定义异常处理ora-02291错误
  • 自定义异常

    在上面“使用非预定义异常处理ora-02291错误”的示例代码中,如果输入一个不存在的雇员的first_name,将不会更新到行数据,不会触发e_int这个非预定义异常,PL/SQL将不会给出任何提示信息。如果此时需要获取到某些信息,或者做某些操作的话,就需要用到自定义异常了,使用步骤:

      a)定义异常标识符。必须在定义部分定义。

    b)主动触发异常。使用RAISE语句显式触发。

    c)捕获并处理异常。

  示例:

 1 DECLARE
 2    e_int EXCEPTION;
 3    e_int_norows EXCEPTION;
 4    PRAGMA EXCEPTION_INIT(e_int,-2291);
 5    v_name emp_learn.first_name%TYPE:=LOWER('&name');
 6    v_deptno dept_learn.department_id%TYPE:=&dno;    
 7 BEGIN
 8    UPDATE emp_learn SET department_id=v_deptno WHERE LOWER(first_name) = v_name;
 9    IF SQL%NOTFOUND THEN
10       RAISE e_int_norows;
11    END IF;
12 EXCEPTION
13    WHEN e_int THEN
14       dbms_output.put_line('该部门不存在!');
15    WHEN e_int_norows THEN
16       dbms_output.put_line('该雇员不存在!');
17 END;
使用自定义异常

使用异常处理函数

   异常处理函数用于取得oracle错误号和错误消息,其中函数SQLCODE用于取得错误号,SQLERRM用于取得错误消息。当编写PL/SQL块时,通过在异常处理部分引用函数SQLCODE和SQLERRM,可以取得未预计到的oracle错误。通过使用内置过程RAISE_APPLICATION_ERROR,可以在建立子程序(过程、函数和包)时自定义错误号和错误消息。

  RAISE_APPLICATION_ERROR过程只适用于数据库子程序(过程、函数、包、触发器),语法:

  raise_application_error(error_number,message,[,{TRUE | FALSE}]);

  当第三个参数设置为TRUE,则错误会存放到先前错误堆栈,否则会替换先前所有错误。

    示例:

 1 DECLARE
 2    e_int EXCEPTION;
 3    PRAGMA EXCEPTION_INIT(e_int,-20000);
 4 BEGIN
 5    DELETE FROM dept_learn WHERE department_id=&dno;
 6    IF SQL%NOTFOUND THEN
 7       raise_application_error(-20000,'该部门不存在!');
 8    END IF;
 9 EXCEPTION 
10    WHEN e_int THEN
11       dbms_output.put_line('错误号:'||SQLCODE||',错误消息:'||SQLERRM);
12    WHEN OTHERS THEN 
13       dbms_output.put_line('others-错误号:'||SQLCODE||',错误消息:'||SQLERRM);
14 END;
使用异常函数

 

使用编译警告

    使用比较少,以后在加上去。

原文地址:https://www.cnblogs.com/shizhongxing/p/3283210.html