PLSQL存储过程调用存储过程对异常的处理问题

简介:

开始

如果对异常处理不正确,有可能会导致意想不到的结果。下面这个就是:

先写两个存储过程 test01 和  test02:

复制代码
CREATE OR REPLACE PROCEDURE test01 IS

v_id emp.empno%TYPE;

BEGIN
   UPDATE emp SET ename='test01' WHERE empno=7369;

   /*this will raise no_data_found exception*/
   SELECT empno INTO v_id FROM emp WHERE empno=12345; 
END;

CREATE OR REPLACE PROCEDURE test02 IS

BEGIN
  UPDATE emp SET ename='test02' WHERE empno=7499;
  
  /*call another procedure*/
  test01;
  
EXCEPTION
  
  WHEN NO_DATA_FOUND THEN
     DBMS_OUTPUT.PUT_LINE('execption occured.!');
  
END;
复制代码

test02 调用 test01 ,由于 test01处理SQL文的时候,select 语句试图查找一条并不存在的记录,导致 NO_DATA_FOUND 发生。

而这个异常实际上是发生在test01 内部,但是test01 没有处理这个异常的代码逻辑,所以就抛给了test02。

然后,按照 oracle 文档的说法:

test02 处理完此 NO_DATA_FOUND 异常后,因为异常已经处理完毕,所以test01的异常之前的代码并没有rollback,而是继续和 test02 中的语句一起参与运算,最终一起被提交。

所以查询结果是:

empno 为 7369 和 7499 的数据都被改变了!

不过,目前这个结论还不太可靠,因为,单纯的异常并没使得SQL失效。比如下例:

复制代码
CREATE OR REPLACE PROCEDURE test03 IS

v_id emp.empno%TYPE;

BEGIN
   UPDATE emp SET ename='test03' WHERE empno=7369;

   /*this will raise no_data_found exception*/
   SELECT empno INTO v_id FROM emp WHERE empno=12345; 
 
EXCEPTION
   WHEN OTHERS THEN
     DBMS_OUTPUT.PUT_LINE('Exception Occured!');
END;
复制代码

结束





本文转自健哥的数据花园博客园博客,原文链接:http://www.cnblogs.com/gaojian/archive/2012/11/23/2784734.html,如需转载请自行联系原作者

目录
相关文章
|
5月前
|
存储 SQL 数据库连接
C#程序调用Sql Server存储过程异常处理:调用存储过程后不返回、不抛异常的解决方案
本文分析了C#程序操作Sql Server数据库时偶发的不返回、不抛异常问题,并提出了解决思路。首先解析了一个执行存储过程的函数`ExecuteProcedure`,其功能是调用存储过程并返回影响行数。针对代码执行被阻塞但无异常的情况,文章总结了可能原因,如死锁、无限循环或网络问题等。随后提供了多种解决方案:1) 增加日志定位问题;2) 使用异步操作提升响应性;3) 设置超时机制避免阻塞;4) 利用线程池分离主线程;5) 通过信号量同步线程;6) 监控数据库连接状态确保可用性。这些方法可有效应对数据库操作中的潜在问题,保障程序稳定性。
390 11
|
存储 Java 数据库
JAVAEE框架数据库技术之13_oracle 之PLSQL技术及存储过程和函数(二)
JAVAEE框架数据库技术之13_oracle 之PLSQL技术及存储过程和函数
139 0
|
存储 SQL Java
JAVAEE框架数据库技术之13_oracle 之PLSQL技术及存储过程和函数(一)
JAVAEE框架数据库技术之13_oracle 之PLSQL技术及存储过程和函数
132 0
|
存储 SQL Perl
PostgreSQL plpgsql 存储过程、函数 - 状态、异常变量打印、异常捕获... - GET [STACKED] DIAGNOSTICS
标签 PostgreSQL , GET , STACKED , DIAGNOSTICS 背景 使用GET STACKED DIAGNOSTICS捕获异常时的STACK内容。 使用GET DIAGNOSTICS捕获运行过程中的状态值。
4841 0
|
8月前
|
存储 Java 关系型数据库
java调用mysql存储过程
在 Java 中调用 MySQL 存储过程主要借助 JDBC(Java Database Connectivity)。其核心原理是通过 JDBC 与 MySQL 建立连接,调用存储过程并处理结果。具体步骤包括:加载 JDBC 驱动、建立数据库连接、创建 CallableStatement 对象、设置存储过程参数并执行调用。此过程实现了 Java 程序与 MySQL 数据库的高效交互。
|
7月前
|
存储 关系型数据库 MySQL
【YashanDB知识库】MySQL返回结果集的存储过程的改写方法
本文介绍了将MySQL存储过程改写至YashanDB的解决方案。由于MySQL存储过程可直接返回结果集,而YashanDB需通过返回SYS_REF_CURSOR的函数实现类似功能,因此需要对代码进行转换。示例中展示了如何将MySQL存储过程`proc1`改写为YashanDB函数,并调整JDBC应用代码以适配REF_CURSOR输出参数,从而正确获取查询结果。此方法确保了跨数据库场景下的兼容性与功能性。