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;


  • 相关阅读:
    UVALive 5983 MAGRID DP
    2015暑假训练(UVALive 5983
    poj 1426 Find The Multiple (BFS)
    poj 3126 Prime Path (BFS)
    poj 2251 Dungeon Master 3维bfs(水水)
    poj 3278 catch that cow BFS(基础水)
    poj3083 Children of the Candy Corn BFS&&DFS
    BZOJ1878: [SDOI2009]HH的项链 (离线查询+树状数组)
    洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)
    洛谷P3065 [USACO12DEC]第一!First!(Trie树+拓扑排序)
  • 原文地址:https://www.cnblogs.com/pacoson/p/3523489.html
Copyright © 2011-2022 走看看