【问题标题】:Catch Error/Exception In For Loop Oracle在 For 循环 Oracle 中捕获错误/异常
【发布时间】:2015-03-05 23:46:07
【问题描述】:

我有一个动态生成物化视图刷新的循环。但是,我知道随着时间的推移,链接可能会过时,甚至物化视图也可能会被删除。

我想捕获此循环中的任何错误,以便在出现错误时继续执行。

for dbname in (    select distinct db_nm from app_own ) loop 
    dbms_mview.refresh('MV_' || dbname.db_nm || '_ReTable', method => 'C', atomic_refresh=> true);

end loop;

下面是我通常用来捕获错误的内容...我已将它放在下面的循环中,但是我收到一个错误,告诉我异常行不是预期的。将这段代码直接放在结束循环之后会导致捕获一个错误,但不是全部。如何利用这个循环和下面的异常部分来捕获并继续整个循环?

EXCEPTION
      WHEN OTHERS THEN
        l_errcode    := SQLCODE;
        l_errmessage := SUBSTR(SQLERRM,1,50);
        INSERT INTO log_table (program, code, message, info)
          VALUES (l_this_prog, l_errcode, l_errmessage, 'procedure had an error while running ');

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    只需在循环中使用嵌套块:

    for dbname in (    select distinct db_nm from app_own ) loop 
        begin
            dbms_mview.refresh('MV_' || dbname.db_nm || '_ReTable', method => 'C', atomic_refresh=> true);
        EXCEPTION
            WHEN OTHERS THEN
                l_errcode    := SQLCODE;
                l_errmessage := SUBSTR(SQLERRM,1,50);
                INSERT INTO log_table (program, code, message, info)
                VALUES (l_this_prog, l_errcode, l_errmessage,
                    'procedure had an error while running ');
        end;
    end loop;
    

    异常处理程序对其块是本地的,因此它仅适用于内部beginend 之间的过程调用。如果过程调用确实引发了异常,则处理程序将记录该异常,并在该内部块的end 之后继续执行 - 在这种情况下,恰好在循环结束时,因此它将再次绕过循环并处理下一个光标行。

    【讨论】:

    • 应该提到,在这个循环之后我还有额外的代码。当我按照您的建议进行操作时,其余代码似乎没有触发。当我根本不使用异常处理时,我得到了预期的输出,但我失去了故障保护。我怎样才能启动其余的程序?
    • 我很抱歉,最后我有一个额外的例外条款(同时执行我在问题中提出的两种解决方案)。你的补充和解释是有道理的,我不能相信那是我的错误。谢谢!
    • @ZAX - 不知道你的意思。过程调用的异常将导致您的错误记录代码运行,但随后会继续;它对循环后的任何内容都没有影响。哦...好吧,但是你没有从这个内部处理程序传播异常,所以即使你有一个外部异常处理程序,它也不会命中。
    猜你喜欢
    • 1970-01-01
    • 2015-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多