2016-05-23 25 views
0

我有PL/SQL代码,其中在执行插入到表1中并基于某些条件从表2中删除,如果删除成功,则提交所有以上的staments并插入在表3中,状态为'cond_true'else回滚所有上述事务并插入到表3'cond_false'中。如果在此代码中使用提交和回滚,它将关闭打开的光标,并且必须重新为每个光标重新迭代或失败,并且没有光标打开状态。使用roolback/commit将所有光标聚焦,如何超过

OPEN cursor1;  
    Loop    
     fetch cursor1 into tbls; 
     exit when cursor1%notfound;      

      execute immediate INSERT INTO table1 SELECT * FROM table2; 
      -- commit only if below condition is true else rollback; 

     BEGIN 
      IF some_condition THEN 
       -- this condition will become true only after the above insert is executed successfully for all rows 
       execute immediate DELETE FROM table2 where some_condition2; 

       INSERT INTO table3 values('contition_true'); 
       -- commit; 
      ELSE 
       INSERT INTO table3 values('contition_false'); 
       --- first rollback the first insert and then commit only this statement; 
      END IF; 
     END; 
    END LOOP; 
close cursor1; 
+0

什么让你认为光标在提交/回滚时关闭?另外,在这个特定的例子中,光标的点是什么?您不会引用循环内的光标。 – Boneist

+0

在oracle回滚和提交中,关闭所有打开的游标。在上面的例子中,游标包含table1和table2的表名 –

回答

0

我不确定你的意思是提交/回滚关闭游标。你在说什么光标?你正在循环的游标,或循环内的删除/插入语句?

提交/回滚将关闭事务,但不关闭游标。如果是这样的话,下面的代码将错误会循环轮光标第二次,但你会注意到,这不:

begin 
    for rec in (select level lvl from dual connect by level <= 5) 
    loop 
    dbms_output.put_line('lvl = '||rec.lvl); 
    commit; 
    end loop; 
end; 
/

lvl = 1 
lvl = 2 
lvl = 3 
lvl = 4 
lvl = 5 

也许你在谈论跨越提交获取?如果是这样,请查看this AskTom question

或者你的光标是FOR UPDATE?如果是这样,那么做一个提交将释放锁并关闭游标。在你的例子中,我看不到任何证据表明你需要一个游标循环(或者你为什么需要立即执行语句)。循环内部和产生它的光标之间似乎没有联系。如果我是你,我会尝试用一系列基于静态集合的删除/插入来重写整个事情,而不是逐行地做所有事情。

+0

感谢Boneist for for循环将代替游标循环。正如我所说的,上面给出的代码是一个大动态过程的样本,它迭代了多组表并且具有不同的结构;所以不能使用静态语句。游标具有表名和列名。 –

相关问题