当前位置: 代码迷 >> Oracle技术 >> oracle 捕获错误不中断游标循环
  详细解决方案

oracle 捕获错误不中断游标循环

热度:157   发布时间:2016-04-24 08:09:44.0
oracle 捕获异常不中断游标循环
一个简单的存储过程,即从t_information表取数据至t_information_back表,并数据取出后删除t_information的数据,ID是主键,原本想有异常后捕获,循环继续,可test下来,捕获异常,循环也终止了,不知何处有不当之处


CREATE OR REPLACE PROCEDURE PRO_Info_BACK IS
 BACKTIME VARCHAR(20);
 I        NUMBER;
 CURSOR CUR_Info IS
 
  SELECT * FROM t_information T ;
 
BEGIN

 I        := 0;
 
 FOR SOR_Info IN CUR_Info LOOP
 
  BEGIN
   SAVEPOINT SP;
   I := I + 1;
   INSERT INTO t_information_BACK
   VALUES
    (SOR_Info.ID,
     SOR_Info.name,
     SOR_Info.code,
     SOR_Info.time,
     );
  
   DELETE FROM t_information T WHERE T.ID = SOR_Info.ID;
   IF I MOD 1000 = 0 THEN
    COMMIT;
   END IF;
  
  EXCEPTION
   WHEN OTHERS THEN
    ROLLBACK TO SP;
   
    WRITE_ERROR_LOG('PRO_DIALLOST_BACK',
                   '1',
                   SQLCODE,
                   SUBSTR(SQLERRM, 0, 1000));
  END;
 
 END LOOP;
 COMMIT;
END PRO_Info_BACK;

------解决方案--------------------
结构没问题,是你用错了方法,不要用rollback to,设置个标签,用goto.
------解决方案--------------------
其实,思路有问题,不要靠系统异常来处理错误,严谨的程序应该应该是在游标内部就做好各种异常判断,异常则跳过处理,直接fetch到下一条记录
------解决方案--------------------
估计你的循环终止是  WRITE_ERROR_LOG 又产生了异常吧?
不然循环应该是不会终止的应该
还有 你每次循环都有SAVEPOINT SP;
但是你却是1000条才提交一次,这次数不一致
你应该在保存的时候 标记下次  然后下次循环再设置保存点SAVEPOINT
还有 你这里应该没有必要1000条保存一次 尽早保存可以提高效率  
不然oracle 还要帮你维护 以便考虑你之后要回滚
------解决方案--------------------
刚测试了下  设置同一个保存点名称之间  如果中间没有提交 第2个保存点 会自动提交之前的记录
------解决方案--------------------
上条说错了,你的sp 可以重复使用 每次回滚 都只是回滚到最近的一个指定名称的保存点
比如  SAVEPOINT SP;
dml语句1....
 SAVEPOINT SP;
dml 语句2。。。
 ROLLBACK TO SP;
 ROLLBACK TO SP;
第一个回滚语句只回滚dml语句2
第2个回滚语句没有效果 不会回滚dml语句1
如果有这样地方需求 则需要创建不同的 保存点名称了
可以这样理解:当创建一个同样名称的保存点之后, 之前的相同名称的保存点就不再存在,相当于你之前从来没创建过一样
  相关解决方案