• PL/SQL学习(五)异常处理


    原文参考:http://plsql-tutorial.com/

    组成:
    1) 异常类型
    2) 错误码
    3) 错误信息
     
    代码结构:
    DECLARE
    Declaration section
    BEGIN
    Exception section
    EXCEPTION
    WHEN ex_name1 THEN
    -Error handling statements
    WHEN ex_name2 THEN
    -Error handling statements
    WHEN Others THEN
    -Error handling statements
    END;
    嵌套的PL/SQL块里如果有异常抛出,且没有进行异常处理时,
    异常会交给最近的上层PL/SQL块进行处理,如果上层块中还是
    没有进行处理,程序将在异常发生时退出。
     
    异常类型:
    a) 系统异常
     
    异常名称 发生原因 错误码
    CURSOR_ALREADY_OPEN 打开一个已经打开的游标 ORA-06511
    INVALID_CURSOR 错误的游标操作,如关闭未打开游标或者从未打开游标里取数据。 ORA-01001
    NO_DATA_FOUND SELECT...INTO语句没能取到数据 ORA-01403
    TOO_MANY_ROWS SELECT or fetch超过一行数据到变量或者记录里 ORA-01422
    ZERO_DIVIDE 除0操作 ORA-01476
    例子:
    BEGIN
    取数据操作
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
    dbms_output.put_line ('A SELECT...INTO did not return any row.');
    END;
     
    b) 未命名系统异常
     
    两种使用方式:
    1.使用WHEN OTHERS异常处理器
    2.将错误码关联到一个名字来将未命名系统异常当做已命名的使用
     
    格式:
    DECLARE
    exception_name EXCEPTION;
    PRAGMA
    EXCEPTION_INIT (exception_name, Err_code);
    BEGIN
    Execution section
    EXCEPTION
    WHEN exception_name THEN
    handle the exception
    END;
    (注:PRAGMA EXCEPTION_INIT的作用是将一个预先定义的Oracle错误码
    关联到用户定义的异常名
     
    例子(未删除子表中记录的情况下删除父表中的记录):
    DECLARE
    Child_rec_exception EXCEPTION;
    PRAGMA
    EXCEPTION_INIT (Child_rec_exception, -2292);
    BEGIN
    Delete FROM product where product_id= 104;
    EXCEPTION
    WHEN Child_rec_exception
    THEN Dbms_output.put_line('Child records are present for this product_id.');
    END;
    /
    c) 用户自定义异常
    例子(订单数量超过20时报异常):
    DECLARE
    huge_quantity EXCEPTION;
    CURSOR product_quantity is
    SELECT p.product_name as name, sum(o.total_units) as units
    FROM order_items o, product p
    WHERE o.product_id = p.product_id;
    quantity order_items.total_units%type;
    up_limit CONSTANT order_items.total_units%type := 20;
    message VARCHAR2(50);
    BEGIN
    FOR product_rec in product_quantity LOOP
    quantity := product_rec.units;
    IF quantity > up_limit THEN
    message := 'The number of units of product ' || product_rec.name ||
    ' is more than 20. Special discounts should be provided.
    Rest of the records are skipped. '
    RAISE huge_quantity;
    ELSIF quantity < up_limit THEN
    message := 'The number of unit is below the discount limit.';
    END IF;
    dbms_output.put_line (message);
    END LOOP;
    EXCEPTION
    WHEN huge_quantity THEN
    dbms_output.put_line (message);
    END;
    /
     
    RAISE_APPLICATION_ERROR ( )
    这是一个Oracle内嵌的存储过程,用来错误码范围在-20000到-20999之间用户自定义异常。
    当使用这个时,所有未提交的事务都将自动回滚。
    这个操作只触发操作异常,而不对异常进行处理。
     
    RAISE_APPLICATION_ERROR()作用
    a) 为用户自定义异常绑定一个错误码
    b) 使得用户自定义异常看起来跟Oracle错误一样
     
    语法格式:
    RAISE_APPLICATION_ERROR (error_number, error_message);
     
    例子:
    DECLARE
    huge_quantity EXCEPTION;
    CURSOR product_quantity is
    SELECT p.product_name as name, sum(o.total_units) as units
    FROM order_items o, product p
    WHERE o.product_id = p.product_id;
    quantity order_items.total_units%type;
    up_limit CONSTANT order_items.total_units%type := 20;
    message VARCHAR2(50);
    BEGIN
    FOR product_rec in product_quantity LOOP
    quantity := product_rec.units;
    IF quantity > up_limit THEN
    RAISE huge_quantity;
    ELSIF quantity < up_limit THEN
    message:= 'The number of unit is below the discount limit.';
    END IF;
    Dbms_output.put_line (message);
    END LOOP;
    EXCEPTION
    WHEN huge_quantity THEN
    raise_application_error(-2100, 'The number of unit is above the discount limit.');
    END;
    /
     
     
  • 相关阅读:
    delphi 常用的将窗口置前的函数
    delphi中Message消息的使用方法
    批处理 删除文件
    CDR话单主要字段介绍
    集成学习算法总结----Boosting和Bagging
    Benchmark简介
    脚本中export不起作用的原因分析
    RAID详解[RAID0/RAID1/RAID10/RAID5]
    基于DPI(深度报文解析)的应用识别
    DPI (Deep Packet Inspection) 深度包检测技术
  • 原文地址:https://www.cnblogs.com/goingforward/p/5848501.html
Copyright © 2020-2023  润新知