【问题标题】:Is it possible to CONTINUE a loop from an exception?是否可以从异常中继续循环?
【发布时间】:2011-08-19 16:04:06
【问题描述】:

我有一个在循环内执行的 fetch。如果此提取失败(无数据)我想 CONTINUE 循环到 EXCEPTION 中的下一条记录。

这可能吗?

我收到了ORA-06550 & PLS-00201 identifer CONTINUE must be declared

DECLARE
   v_attr char(88);
CURSOR  SELECT_USERS IS
SELECT id FROM USER_TABLE
WHERE USERTYPE = 'X';
BEGIN
    FOR user_rec IN SELECT_USERS LOOP    
        BEGIN
            SELECT attr INTO v_attr 
            FROM ATTRIBUTE_TABLE
            WHERE user_id = user_rec.id;            
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               -- user does not have attribute, continue loop to next record.
               CONTINUE;
         END;         
    END LOOP;
END;

【问题讨论】:

标签: oracle plsql


【解决方案1】:

CONTINUE 语句是 11g 中的一个新特性。

这是一个相关的问题:'CONTINUE' keyword in Oracle 10g PL/SQL

【讨论】:

    【解决方案2】:

    在您提供的构造中,您不需要继续。处理完异常后,将执行 END 之后的语句,假设您的 EXCEPTION 块不会终止该过程。换句话说,它将继续到 user_rec 循环的下一次迭代。

    您还需要在 BEGIN 块中选择一个变量:

    SELECT attr INTO v_attr FROM attribute_table...
    

    显然你也必须声明 v_attr...

    【讨论】:

    • 谢谢,我做了一个快速而肮脏的例子,你选择变量是对的。
    【解决方案3】:

    ole goto 语句怎么样(我知道,我知道,但它在这里工作得很好;)

    DECLARE
       v_attr char(88);
    CURSOR  SELECT_USERS IS
    SELECT id FROM USER_TABLE
    WHERE USERTYPE = 'X';
    BEGIN
        FOR user_rec IN SELECT_USERS LOOP    
            BEGIN
                SELECT attr INTO v_attr 
                FROM ATTRIBUTE_TABLE
                WHERE user_id = user_rec.id;            
             EXCEPTION
                WHEN NO_DATA_FOUND THEN
                   -- user does not have attribute, continue loop to next record.
                   goto end_loop;
             END;
    
            <<end_loop>>
            null;         
        END LOOP;
    END;
    

    当然,只需将 end_loop 放在循环的末尾即可。 null 可以用提交或计数器增量替换,这取决于您。

    【讨论】:

      【解决方案4】:

      对于这个例子,你真的应该只使用外连接。

      declare
      begin
        FOR attr_rec IN ( 
          select attr 
          from USER_TABLE u 
          left outer join attribute_table a 
          on ( u.USERTYPE = 'X' and a.user_id = u.id ) 
        ) LOOP
          <process records> 
          <if primary key of attribute_table is null 
           then the attribute does not exist for this user.>
        END LOOP;
      END;
      

      【讨论】:

        【解决方案5】:

        请注意,您可以像使用 WHEN exception THEN continue 一样使用 WHEN exception THEN NULL。示例:

            DECLARE
                extension_already_exists  EXCEPTION;
                PRAGMA EXCEPTION_INIT(extension_already_exists, -20007);
                l_hidden_col_name  varchar2(32);
            BEGIN
                FOR t IN (  SELECT table_name, cast(extension as varchar2(200)) ext
                            FROM all_stat_extensions
                            WHERE owner='{{ prev_schema }}'
                              and droppable='YES'
                            ORDER BY 1
                         )
                LOOP
                    BEGIN
                        l_hidden_col_name := dbms_stats.create_extended_stats('{{ schema }}', t.table_name, t.ext);
                    EXCEPTION
                        WHEN extension_already_exists THEN NULL;   -- ignore exception and go to next loop iteration
                    END;
                END LOOP;
            END;
        

        【讨论】:

          猜你喜欢
          • 2013-02-05
          • 2020-09-21
          • 2012-12-05
          • 1970-01-01
          • 1970-01-01
          • 2020-07-01
          • 2018-03-20
          • 2015-08-19
          • 2021-03-25
          相关资源
          最近更新 更多