Oracle PL/SQL开发基础(第三十六弹:异常处理的一些经验)
来源:互联网 发布:领啦试用网站源码 编辑:程序博客网 时间:2024/06/05 17:28
从异常中恢复
当触发异常以后,代码的执行立即跳转到异常处理部分,异常处理部分结束后,语句块就终止了。如果在处理完异常之后想继续执行抛出异常的地方后面的代码,可以将异常包装在子块中,在子块中写对应的异常控制程序,这样一旦在子块中有错误发生,子块内部的异常处理器就捕获异常。当子块结束时,就可以继续执行外层块中的下一条语句。
获取异常抛出的位置
如下代码:
DECLARE ...BEGIN SELECT sal INTO v_sal1 FROM emp WHERE empno = '1'; SELECT sal INTO v_sal2 FROM emp WHERE empno = '2'; SELECT sal INTO v_sal3 FROM emp WHERE empno = '3';EXCEPTION WHEN NO_DATA_FOUND THEN ...END;
当触发了NO_DATA_FOUND
异常时,怎么知道是哪个SELECT语句触发了异常呢?
方法一:使用计数器
如:
DECLARE v_count NUMBER := 1;BEGIN SELECT sal INTO v_sal1 FROM emp WHERE empno = '1'; v_count := 2; SELECT sal INTO v_sal2 FROM emp WHERE empno = '2'; v_count := 3; SELECT sal INTO v_sal3 FROM emp WHERE empno = '3';EXCEPTION WHEN NO_DATA_FOUND THEN ...END;
触发异常时,根据计数器就能跟踪到时哪个语句触发了异常。
方法二:使用子块
将每一个SELECT语句分别定义到一个子块中,每个子块中都可以捕获异常。如:
DECLARE ...BEGIN BEGIN SELECT sal INTO v_sal1 FROM emp WHERE empno = '1'; EXCEPTION WHEN NO_DATA_FOUND THEN ... END; BEGIN SELECT sal INTO v_sal2 FROM emp WHERE empno = '2'; EXCEPTION WHEN NO_DATA_FOUND THEN ... END; BEGIN SELECT sal INTO v_sal3 FROM emp WHERE empno = '3'; EXCEPTION WHEN NO_DATA_FOUND THEN ... END;EXCEPTION WHEN NO_DATA_FOUND THEN ...END;
方法三:使用DBMS_UTILITY.FORMAT_ERROR_BACK_TRACE
函数
这个函数是Oracle 10g以后的版本提供的。在异常处理程序中调用这个函数来访问异常的栈,它可以返回错误发生的行号。
异常与事务处理
抛出一个异常并不会终止一个事务,除非显式的调用了ROLLBACK或COMMIT。但是这里有一个问题,如果顶层的语句块存在一个未处理的异常,该异常将被传递到调用环境,那么事务将被服务器端自动回滚。
如果想在异常发生后,不放弃事务,不进行回滚,重新再处理一次,可以按如下三步来实现:
1. 将事务放在一个子块中。
2. 把子块放入一个循环,重复执行事务。
3. 在开始事务之前标记一个保存点,如果事务执行成功,就提交事务并退出循环,如果执行失败,就将控制权交给异常处理程序,事务回滚到保存点,然后重新执行事务。
如:
BEGIN LOOP BEGIN SAVEPOINT 开始事务; ... IF ... THEN RAISE e_some_exception; END IF; ... COMMIT; EXIT; EXCEPTION WHEN e_some_exception THEN ROLLBACK TO 开始事务; ... -- 这里可以为一些变量重新赋值等等,重新开始循环执行。
阅读全文
1 0
- Oracle PL/SQL开发基础(第三十六弹:异常处理的一些经验)
- Oracle PL/SQL开发基础(第三十五弹:异常的传递)
- Oracle PL/SQL开发基础(第十九弹:集合的异常处理)
- Oracle PL/SQL开发基础(第三十一弹:自定义异常)
- Oracle PL/SQL开发基础(第二十九弹:异常处理简介)
- Oracle PL/SQL开发基础(第三弹:修改表)
- Oracle PL/SQL开发基础(第三十三弹:EXCEPTION_INIT)
- Oracle PL/SQL开发基础(第三十四弹:RAISE_APPLICATION_ERROR)
- Oracle PL/SQL开发基础(第二十六弹:游标变量)
- Oracle PL/SQL开发基础(第三十二弹:SQLCODE和SQLERRM)
- Oracle PL/SQL开发基础(第三十弹:预定义异常)
- Oracle:pl/sql 异常处理
- Oracle:pl/sql 异常处理
- Oracle PL/SQL异常处理
- Oracle PL/SQL异常处理
- Oracle PL/SQL开发入门(第三弹:变量)
- Oracle PL/SQL处理CLOB字段的经验
- 【Oracle】Oracle PL/SQL处理异常的特殊方法
- springmvc全局异常处理器的配置
- 2186. 猴子拆房
- 解析URL
- MySQL 性能优化
- erase()的使用
- Oracle PL/SQL开发基础(第三十六弹:异常处理的一些经验)
- 12.接口:implements
- junit5相关依赖的写法
- Leaf Classification
- sklearn中文api翻译
- 各种排序算法的积累
- ServiceWorker
- 2017.08.15总结
- 写给自己的Java程序员学习路线图