• 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;
    使用异常函数

     

    使用编译警告

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

  • 相关阅读:
    The Princess and the Pea,摘自iOS应用Snow White and more stories
    Android笔记之自定义的RadioGroup、RadioButton,以及View实例状态的保存与恢复
    Android笔记之获取debug.keystore和release.keystore的MD5/SHA1值
    Android笔记之WebView加载网页的进度回调
    Android Studio停留在“Indexing paused due to batch update”的解决方案
    【Python初级】StringIO和BytesIO读写操作的小思考
    【Python初级】由判定回文数想到的,关于深浅复制,以及字符串反转的问题
    【Python初级】由生成杨辉三角代码所思考的一些问题
    【面试总结-编程】多行两列数据,实现同key的value求和并输出
    【算法与数据结构实战】模拟竖式加法,自定义位数
  • 原文地址:https://www.cnblogs.com/shizhongxing/p/3283210.html
Copyright © 2020-2023  润新知