PLSQL oracle 的 FOR 循环中是不是需要保存点?

Posted

技术标签:

【中文标题】PLSQL oracle 的 FOR 循环中是不是需要保存点?【英文标题】:Is savepoint required inside FOR loop of PLSQL oracle?PLSQL oracle 的 FOR 循环中是否需要保存点? 【发布时间】:2020-03-02 16:17:26 【问题描述】:

只是想知道如果我们内部有异常捕获,我们是否真的需要在 LOOP 语句中需要回滚/保存点。

create table my_Tab
(id number,
name varchar2(10),
address varchar2(100));

insert into my_tab values (1,'ABC','XXX');
insert into my_tab values (2,'DEF','YYY');
insert into my_tab values (3,'GHI','ZZZ');
insert into my_tab values (4,'JKL',null);

DECLARE
CURSOR cur_my_tab is
select * from my_tab;
l_var varchar2(100);
l_count number := 0;
begin
for rec_my_tab in cur_my_tab
loop
    BEGIN
    dbms_output.put_line('id' || rec_my_tab.id);
    --savepoint sv_cur_my_tab;
        dbms_output.put_line('name' || rec_my_tab.name);
        select rec_my_tab.address into l_var from dual;
        update my_Tab set id = id +4 where id = rec_my_tab.id;
        dbms_output.put_line(l_var);
        if rec_my_tab.address ='xxx' then
            l_count:= rec_my_tab.id/l_count;
        END IF;
    Exception
        when others then 
            dbms_output.put_line('in inner exception');
            --rollback to sv_cur_my_tab;*/
    end;
end loop;
Exception
    when others then 
        dbms_output.put_line('in outer exception');
        --rollback to sv_cur_my_tab;
end;

我有 2 个高于查询的查询。

    提交按上述顺序何时发生。 在上面的代码中,考虑到异常是在光标中间抛出的(如第 3 次或第 4 次迭代)。添加回滚和保存点会对此进行更改吗?目前,整个循环已完成,所有更新也正在提交中。

【问题讨论】:

为什么所有这些 pl/sql 循环都是为了一个简单的更新语句?逐行处理非常低效。你不应该使用“当别人”如果有异常,那么你需要确定原因,而不是忽略它。 【参考方案1】:

上述顺序中的提交何时发生?

它没有。至少,我没有看到commit 声明。也许我是个盲人。但是 PL/SQL 中没有“自动提交”。因此,commit 在您发出一个(或您的客户端软件发出)之前不会发生。

在上面的代码中,考虑到异常是在光标中间抛出的(比如第 3 次或第 4 次迭代)。添加回滚和保存点会对此进行更改吗?目前,整个循环已完成,所有更新也正在提交中。

当您在游标循环中有多个 DML 语句并且你们都有时,回滚到保存点通常很有用

    希望确保对于每个游标记录,DML 语句 要么全部成功,要么都不成功 在处理完所有行之前不想提交任何内容

在您的情况下,循环内只有一个update,然后更改“l_count”变量的值。如果您希望在更改 'l_count' 发生任何问题时回滚更新,您需要回滚到保存点。

请记住,回滚到保存点不会恢复对 PL/SQL 变量的任何更改,例如“l_count”。在回滚到保存点之前,您有责任根据需要恢复它们的值。

【讨论】:

以上是关于PLSQL oracle 的 FOR 循环中是不是需要保存点?的主要内容,如果未能解决你的问题,请参考以下文章

关于游标和for循环的问题

Oracle/PLSQL 在 BULK COLLECT 之后处理 for LOOP 中的所有数据

Oracle存储过程游标for循环怎么写

Oracle 中的光标与 FOR 循环

Oracle存储过程游标for循环怎么写

游标loop循环和游标for循环的区别