2008-10-07 9 views
33

Ich migriere eine gespeicherte TSQL-Prozedur nach PL/SQL und habe ein Problem festgestellt - das Fehlen eines CONTINUE-Schlüsselworts in Oracle 10g.'CONTINUE' Schlüsselwort in Oracle 10g PL/SQL

Ich habe gelesen, dass Oracle 11g dies als eine neue Funktion hat, aber ein Upgrade ist leider keine Option.

Gibt es eine Alternative zu WEITER in 10g? Ich glaube nicht, dass es praktisch ist, die Logik des SP als Workaround zu restrukturieren, weil ich eine äußere Schleife, ein IF, dann ein verschachteltes IF und dann den CONTINUE am Ende eines Anweisungsblocks in diesem IF habe.

Jede Hilfe wäre sehr willkommen, Prost.

Antwort

52

Sie können einen Fortsetzungsvorgang mit goto and labels simulieren.

DECLARE 
    done BOOLEAN; 
BEGIN 
    FOR i IN 1..50 LOOP 
     IF done THEN 
     GOTO end_loop; 
     END IF; 
    <<end_loop>> -- not allowed unless an executable statement follows 
    NULL; -- add NULL statement to avoid error 
    END LOOP; -- raises an error without the previous NULL 
END; 
+4

+1 für eine hässliche Problemumgehung, um eine hässliche Aussage zu behandeln :) –

+2

Manchmal müssen wir es nur eingeben und unsere Nasen danach bedecken. :) – jop

+0

Sie können auch ein Konstrukt verwenden, das eine Fortsetzung perfekt nachahmt. Und ohne eine Null hinzuzufügen :) Siehe meine Antwort unten. – SRO

4

Können Sie die IFs zu einer Funktion umgestalten und an der entsprechenden Stelle (früh, falls erforderlich) zurückkehren. Dann wird der Kontrollfluss in der Schleife an der richtigen Stelle aufgenommen.

Macht das Sinn?

1

In Oracle gibt es eine ähnliche Anweisung aufgerufen EXIT dass entweder verlässt eine Schleife oder eine Funktion/Verfahren (wenn es keine Schleife aus, um zu beenden ist). Sie können einen WHEN hinzufügen, um nach einer Bedingung zu suchen.

Sie könnten das obige Beispiel wie folgt umschreiben:

DECLARE 
    done BOOLEAN; 
BEGIN 
    FOR i IN 1..50 LOOP 
    EXIT WHEN done; 
    END LOOP; 
END; 

Dies kann nicht genug sein, wenn Sie aus der Tiefe einiger verschachtelten Schleifen und Logik verlassen wollen, aber viel klarer als ein paar GOTOs ist und NULL.

+1

Die EXIT-Lösung würde in diesem Fall nicht wirklich funktionieren, weil sie die gesamte Schleife beenden würde, anstatt einfach bei der nächsten Wiederholung anzufangen, wie es CONTINUE tun würde. Ich denke, ich werde mit der GOTO-Lösung gehen müssen, freut euch alle für eure Vorschläge! –

5

Es in 10 g nicht verfügbar ist, aber es ist ein new feature in 11G

10

Obwohl es ein wenig komplex und nur ein Fake ist, können Sie Ausnahme auf diese Weise verwenden:

DECLARE 
    i NUMBER :=0; 
    my_ex exception; 
BEGIN 
    FOR i IN 1..10 
    LOOP 
     BEGIN 
     IF i = 5 THEN 
      raise my_ex; 
     END IF; 
     DBMS_OUTPUT.PUT_LINE (i); 
     EXCEPTION WHEN my_ex THEN 
     NULL; 
     END; 
    END LOOP; 

END; 
2

Nicht gerade elegant, aber einfach :

DECLARE 
    done BOOLEAN; 
BEGIN 
    FOR i IN 1..50 LOOP 
     IF done THEN 
     NULL; 
     ELSE 
     <do loop stuff>; 
     END IF; 
    END LOOP; 
END; 
6

Tatsächlich hat PL SQL etwas zu ersetzen, WEITER. Alles, was Sie tun müssen, ist ein Etikett (ein Name) an die Schleife hinzuzufügen:

declare 
    i integer; 
begin 
    i := 0; 

    <<My_Small_Loop>>loop 

     i := i + 1; 
     if i <= 3 then goto My_Small_Loop; end if; -- => means continue 

     exit; 

    end loop; 
end; 
+1

Nur ein bisschen weniger hässlich als die GOTO gefolgt von einer NULL-Linie, aber es funktioniert. Vielen Dank! –

5

Für die Zukunft sucht, in oracle sie, continue Anweisung hinzugefügt 11g, die wie folgt verwendet werden kann:

SQL> BEGIN 
    2  FOR i IN 1 .. 5 LOOP 
    3  IF i IN (2,4) THEN 
    4   CONTINUE; 
    5  END IF; 
    6  DBMS_OUTPUT.PUT_LINE('Reached on line ' || TO_CHAR(i)); 
    7  END LOOP; 
    8 END; 
    9/
Reached on line 1 
Reached on line 3 
Reached on line 5 

PL/SQL procedure successfully completed.