当前位置: 首页 > news >正文

Oracle中自定义异常内置异常嵌套异常的捕获处理

一、异常类型分类

类型说明示例
内置预定义异常Oracle已命名异常(如NO_DATA_FOUND)查询无数据时触发
内置非预定义异常未命名的Oracle错误(需用PRAGMA EXCEPTION_INIT关联)ORA-02290(违反检查约束)
自定义异常用户定义的业务逻辑异常数据校验失败时手动抛出

二、异常处理语法
1. 基本结构

DECLARE-- 声明自定义异常custom_exception EXCEPTION;-- 绑定错误代码到非预定义异常PRAGMA EXCEPTION_INIT(custom_exception, -20001);
BEGIN-- 业务逻辑IF 条件 THENRAISE custom_exception; -- 手动抛出异常END IF;
EXCEPTIONWHEN custom_exception THENDBMS_OUTPUT.PUT_LINE('自定义异常触发');WHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('数据未找到');WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('错误代码: ' || SQLCODE);DBMS_OUTPUT.PUT_LINE('错误信息: ' || SQLERRM);
END;

三、异常语法
1. 自定义异常
步骤说明:

①声明异常:

DECLAREinvalid_salary EXCEPTION;

②关联错误代码(可选):

PRAGMA EXCEPTION_INIT(invalid_salary, -20001);

③抛出异常:

IF salary < 0 THENRAISE invalid_salary;
END IF;

④捕获处理:

EXCEPTIONWHEN invalid_salary THENDBMS_OUTPUT.PUT_LINE('薪资不能为负数');

2. 内置异常处理
常用预定义异常:
NO_DATA_FOUND: SELECT未找到数据
TOO_MANY_ROWS: SELECT返回多行数据
ZERO_DIVIDE: 除数为零
DUP_VAL_ON_INDEX: 唯一索引冲突

-- 示例:
BEGINSELECT * INTO emp_rec FROM emp WHERE emp_id = 999;
EXCEPTIONWHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('员工ID不存在');WHEN TOO_MANY_ROWS THENDBMS_OUTPUT.PUT_LINE('返回多行数据');
END;

3. 嵌套异常处理
结构示例:

DECLAREouter_exception EXCEPTION;
BEGIN<<inner_block>>DECLAREinner_exception EXCEPTION;BEGINRAISE inner_exception;EXCEPTIONWHEN inner_exception THENDBMS_OUTPUT.PUT_LINE('内部异常已处理');RAISE outer_exception; -- 抛出到外层END inner_block;
EXCEPTIONWHEN outer_exception THENDBMS_OUTPUT.PUT_LINE('外部捕获到异常');
END;

详细实例:

DECLARE-- 定义变量和异常v_employee_id employees.employee_id%TYPE := 100;v_salary employees.salary%TYPE;e_negative_salary EXCEPTION; -- 自定义异常:工资为负PRAGMA EXCEPTION_INIT(e_negative_salary, -20001); -- 绑定错误代码
BEGIN-- 外层块BEGIN -- 内层块开始-- 尝试获取员工工资SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id;-- 模拟业务逻辑:检查工资有效性IF v_salary < 0 THENRAISE_APPLICATION_ERROR(-20001, '工资不能为负数'); -- 触发自定义异常END IF;DBMS_OUTPUT.PUT_LINE('内层块:工资处理成功。');EXCEPTION -- 内层异常处理WHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('内层块:员工ID ' || v_employee_id || ' 不存在。');RAISE; -- 重新抛出到外层WHEN e_negative_salary THENDBMS_OUTPUT.PUT_LINE('内层块:异常 - ' || SQLERRM);-- 此处可添加恢复逻辑,如设置默认工资v_salary := 0;DBMS_OUTPUT.PUT_LINE('内层块:工资已重置为0。');END; -- 内层块结束-- 外层业务逻辑(内层未异常终止时执行)DBMS_OUTPUT.PUT_LINE('外层块:更新后工资为 ' || v_salary);EXCEPTION -- 外层异常处理WHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('外层块:错误 - 指定员工不存在。');WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('外层块:未知错误 - ' || SQLERRM);ROLLBACK; -- 示例事务回滚
END;

嵌套结构:

  • 内层块: 处理具体数据库操作(如查询、业务验证),捕获NO_DATA_FOUND(预定义)和自定义异常。
  • 外层块: 处理内层未处理的异常,执行后续业务逻辑或全局错误处理。

异常传播:

  • 内层处理并解决: 如e_negative_salary异常被捕获后重置工资,程序继续执行外层代码。
  • 内层重新抛出: NO_DATA_FOUND在内层处理后通过RAISE传递到外层,触发外层对应处理程序。

自定义异常:

  • 使用RAISE_APPLICATION_ERROR抛出并关联错误代码,PRAGMA
    EXCEPTION_INIT将自定义异常绑定到特定错误号。

事务控制:

  • 外层异常处理中可包含ROLLBACK,确保数据一致性(根据实际业务需求调整)。

嵌套规则:

  • 内部块未处理的异常会自动传递到外层块
  • 使用RAISE可手动将异常传递到上层

四、其他处理
1. 错误日志记录

EXCEPTIONWHEN OTHERS THENINSERT INTO error_log (code, message, time)VALUES (SQLCODE, SQLERRM, SYSDATE);COMMIT;RAISE; -- 继续向上层传递异常
END;

2. 动态错误消息

RAISE_APPLICATION_ERROR(-20001, '订单 ' || order_id || ' 状态无效');

3. 异常传播控制

BEGIN-- 业务逻辑
EXCEPTIONWHEN OTHERS THENIF SQLCODE = -2290 THENDBMS_OUTPUT.PUT_LINE('约束违反');ELSERAISE; -- 继续传播未明确处理的异常END IF;
END;

五、总结
优先级处理:

EXCEPTIONWHEN NO_DATA_FOUND THEN ... -- 特定异常在前WHEN OTHERS THEN ...        -- 通用处理在后

事务控制:

BEGINSAVEPOINT sp1;-- DML操作
EXCEPTIONWHEN OTHERS THENROLLBACK TO sp1;RAISE;
END;

错误代码规范:

  • 自定义错误代码范围:-20000 到 -20999
  • 统一错误消息格式

通过合理使用异常处理机制,可显著提升Oracle程序的健壮性。建议在复杂业务逻辑中优先定义清晰的异常处理策略。

相关文章:

  • Dify X 奇墨科技,让AI大模型从“巨头专属”变为“触手可及”
  • 【PmHub后端篇】PmHub Gateway全局过滤器:接口调用耗时统计及黑白名单配置技术深度解析
  • 【se-res模块学习】结合CIFAR-10分类任务学习
  • 机器学习笔记——特征工程
  • HOW - 在 Mac 上的 Chrome 浏览器中调试 Windows 场景下的前端页面
  • 第五十四篇 AI与数据分析
  • Windows ABBYY FineReader 16 Corporate 文档转换、PDF编辑和文档比较
  • 非对称加密:为什么RSA让“公开传密”成为可能
  • 汽车为什么需要以太网?带宽?实时?
  • 如何在 C# 和 .NET 中打印 DataGrid
  • 2025年APP安全攻防指南:抵御DDoS与CC攻击的实战策略
  • 基于智能家居项目 RGB彩灯(P9813)
  • 一个用C#开发的记事本Notepads开源编辑器
  • 57.[前端开发-前端工程化]Day04-webpack插件模式-搭建本地服务器
  • Matter协议,智能家居生态平台的“共生契约”
  • 系统重装之后,通过ssh无法登录
  • java 破解aspose.words 18.6 使用
  • SEMI E40标准的加工任务状态模型(Process Job State Model)解析
  • 【Python 日期和时间】
  • DLMS协议 —— System title 详解(作用及结构一览)
  • 晶圆销量上升,中芯国际一季度营收增长近三成,净利增超1.6倍
  • 98岁动物学家、北京大学教授杨安峰逝世
  • 加力、攻坚、借力、问效,上海为优化营商环境推出增量举措
  • 美联储宣布维持联邦基金利率目标区间不变
  • 美国与胡塞武装达成停火协议,美伊相向而行?
  • 又一日军“慰安妇”制度受害者去世,大陆在世幸存者仅7人