zoukankan      html  css  js  c++  java
  • oracle PL/SQL(procedure language/SQL)程序设计之异常(exception)

    什么是异常?
    在PL/SQL中的一个标识。
    在程序运行期间被触发的错误。
    异常是怎样被触发的?
    产生一个Oracle错误。
    用户显示触发。
    怎样处理异常?
    用异常处理句柄捕获异常。
    传播异常到调用环境。

    捕获异常

    EXCEPTION
      WHEN exception1 [OR exception2 . . .] THEN
        statement1;
        statement2;
        . . .
      [WHEN exception3 [OR exception4 . . .] THEN
        statement1;
        statement2;
        . . .]
      [WHEN OTHERS THEN
        statement1;
        statement2;
        . . .]
    异常捕获规则

    WHEN OTHERS用于捕获所有未指定错误。必须是最后一个错误处理语句。
    EXCEPTION关键字,标识异常处理的开始区域。
    允许有多个异常处理子句。
    在离开异常处理程序块之前,只能有一个错误处理子句被执行。
    捕获Oracle服务器预定义错误

    CASE_NOT_FOUND  (ORA-06592)
    NO_DATA_FOUND  (ORA-1403)
    TOO_MANY_ROWS  (ORA-1422)
    DUP_VAL_ON_INDEX     (ORA-0001)
    ZERO_DIVIDE (ORA-1476)
    INVALID_CURSOR  (ORA-1001)
    VALUE_ERROR (ORA-6502)
    语法:

    BEGIN  SELECT ... COMMIT;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        statement1;
        statement2;                                  
      WHEN TOO_MANY_ROWS THEN
        statement1;
      WHEN OTHERS THEN
        statement1;
        statement2;
        statement3;
    END;    
    实例

    DECLARE
      v_empRecord  emp%ROWTYPE;
      v_empNo      emp.empno%TYPE;
    BEGIN  
      SELECT *  INTO v_empRecord  FROM emp;
      --SELECT *  INTO v_empRecord  FROM emp  WHERE empno = 12345;
      --SELECT ename  INTO v_empNo  FROM emp  WHERE empno = 7369;
      EXCEPTION
        WHEN TOO_MANY_ROWS THEN
          dbms_output.put_line('TOO_MANY_ROWS EXCEPTION');
        WHEN NO_DATA_FOUND THEN
          dbms_output.put_line('NO_DATA_FOUND EXCEPTION');
        WHEN OTHERS THEN
          dbms_output.put_line('OTHERS EXCEPTION');
    END;

     捕获Oracle服务器错误
    将数字-2292与e_products_invalid相关联。(-2292表示违反了完整性约束)
    DECLARE
      e_products_invalid    EXCEPTION;
      PRAGMA EXCEPTION_INIT (
            e_products_invalid, -2292);
      v_message VARCHAR2(50);
    BEGIN    
    . . .
    EXCEPTION
      WHEN e_products_invalid THEN
        :g_message := 'Product code
            specified is not valid.';
    . . .
    END;
    example
    为emp表创建一个能完成插入功能的存储过程insert_emp。
    CREATE OR REPLACE PROCEDURE insert_emp
    (no IN emp.empno%TYPE,   name IN emp.ename%TYPE DEFAULT NULL,
    job IN emp.job%TYPE DEFAULT 'SALESMAN',
    mgr IN emp.mgr%TYPE DEFAULT 7369,
    hiredate emp.hiredate%TYPE DEFAULT SYSDATE,
    salary emp.sal%TYPE DEFAULT 800,
    comm emp.comm%TYPE DEFAULT NULL,
    deptno emp.deptno%TYPE DEFAULT 10
    )IS
    e_integrity EXCEPTION;
    PRAGMA EXCEPTION_INIT (e_integrity,-2291);
    BEGIN
         INSERT INTO emp VALUES(no,name,job,mgr,hiredate,salary,comm,deptno);
    EXCEPTION
        WHEN DUP_VAL_ON_INDEX THEN
            dbms_output.put_line('该员工已经存在!');
        WHEN e_integrity THEN
            dbms_output.put_line('部门编号填写错误!');
    END;


    example 向emp表中插入一条新记录,在执行的过程中捕获系统预定义异常、系统非预定义异常、用户自定义异常,并分别作相应的处理。
    DECLARE  
      ex_null EXCEPTION; --系统非预定义异常的定义和关联
      PRAGMA EXCEPTION_INIT(ex_null,-01400);  
      ex_insert EXCEPTION; --用户自定义异常的定义  
      eno scott.emp.empno%TYPE:=&no; --定义程序块变量
      e_sal scott.emp.sal%TYPE:=&salary;
    BEGIN
      IF e_sal>10000 THEN
        RAISE ex_insert;  --用户自定义异常的触发
      ELSE
        INSERT INTO scott.emp(empno,sal) VALUES(eno,e_sal);
      END IF;
      EXCEPTION
        WHEN DUP_VAL_ON_INDEX  THEN   --系统预定义异常的捕获和处理
          dbms_output.put_line('该员工已经存在!');
        WHEN ex_null THEN   --系统非预定义异常的捕获和处理
          dbms_output.put_line('职工编号不能为空!');
        WHEN ex_insert THEN   --用户自定义异常的捕获和处理
          dbms_output.put_line('员工的工资不能超过10000!');
    END;


    捕获异常中的函数
     SQLCODE
    返回错误代码。
    SQLERRM
    返回与错误代码相关联的消息。
    DECLARE
      v_error_code      NUMBER;
      v_error_message   VARCHAR2(255);
    BEGIN
    ...
    EXCEPTION
    ...
      WHEN OTHERS THEN
        ROLLBACK;
        v_error_code := SQLCODE ;
        v_error_message := SQLERRM ;
        INSERT INTO errors VALUES(v_error_code,
                       v_error_message);
    END;




    RAISE_APPLICATION_ERROR

     raise_application_error (error_number,
            message[, {TRUE | FALSE}]);    
    从存储过程中触发用户自定义异常。

     ...
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
                 RAISE_APPLICATION_ERROR (-20201,'Manager is not a valid employee.');
         END;
        
    例8.4  为scott.emp表创建一个能完成插入功能的存储过程insert_emp。
    CREATE OR REPLACE PROCEDURE insert_emp
    (no IN scott.emp.empno%TYPE,
    name IN scott.emp.ename%TYPE DEFAULT NULL,
    job IN scott.emp.job%TYPE DEFAULT 'SALESMAN',
    mgr IN scott.emp.mgr%TYPE DEFAULT 7369,
    hiredate scott.emp.hiredate%TYPE DEFAULT SYSDATE,
    salary scott.emp.sal%TYPE DEFAULT 800,
    comm scott.emp.comm%TYPE DEFAULT NULL,
    deptno scott.emp.deptno%TYPE DEFAULT 10
    )
    IS
    e_integrity EXCEPTION;
    PRAGMA EXCEPTION_INIT (e_integrity,-2291);
    BEGIN
    INSERT INTO scott.emp VALUES(no,name,job,mgr,hiredate,salary,comm,deptno);
    EXCEPTION
    WHEN DUP_VAL_ON_INDEX THEN
    dbms_output.put_line('该员工已经存在!');
    WHEN e_integrity THEN
    dbms_output.put_line('部门编号填写错误!');
    END;


  • 相关阅读:
    练习上传下载时遇到的问题
    el表达式遇到的问题
    js中for循环闭包问题记录
    随机排座位(模板) 20.10.17
    #STL:优先队列数据结构函数的用法 #堆 #优先队列数据结构(堆) #priority_queue 20.10.17
    关于int的范围
    #归并排序 归并排序的刷题记录 ~20.09.25
    #欧拉函数 ~20.8.27
    #排列 #组合 ~20.8.24
    105.七夕祭
  • 原文地址:https://www.cnblogs.com/pacoson/p/3523489.html
Copyright © 2011-2022 走看看