it-swarm.com.de

Ist es möglich, eine Schleife aus einer Ausnahme heraus fortzusetzen?

Ich habe einen Abruf, der innerhalb einer Schleife ausgeführt wird. Wenn dieser Abruf fehlschlägt (keine Daten), möchte ich CONTINUE die Schleife zum nächsten Datensatz aus EXCEPTION.

Ist das möglich?

Ich bekomme einen 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;
17

Die CONTINUE-Anweisung ist eine neue Funktion in 11g.

Hier ist eine verwandte Frage: Schlüsselwort 'CONTINUE' in Oracle 10g PL/SQL

13
angus

In dem von Ihnen angegebenen Konstrukt benötigen Sie kein WEITER. Sobald die Ausnahme behandelt wurde, wird die Anweisung nach ENDE ausgeführt, sofern der EXCEPTION-Block die Prozedur nicht beendet. Mit anderen Worten wird mit der nächsten Iteration der user_rec-Schleife fortgefahren.

Sie müssen auch eine Variable innerhalb Ihres BEGIN-Blocks auswählen:

SELECT attr INTO v_attr FROM attribute_table...

Natürlich müssen Sie auch v_attr angeben ...

10
DCookie

Wie wäre es mit der alten goto-Anweisung (ich weiß, ich weiß, aber es funktioniert hier gut;)

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;

Einfach end_loop ganz am Ende der Schleife setzen. Die Null kann durch ein Commit oder ein Zählerinkrement ersetzt werden.

6
tbone

Beachten Sie, dass Sie WHEN exception THEN NULL genauso verwenden können wie WHEN exception THEN continue. Beispiel:

    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;
0
Tagar

Für dieses Beispiel sollten Sie wirklich nur eine äußere Verknüpfung verwenden.

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;
0
bozon