2008-10-07 12 views
33

Dokonuję migracji procedury składowanej TSQL do PL/SQL i napotkałem problem - brak słowa kluczowego CONTINUE w Oracle 10g.Słowo kluczowe "KONTYNUUJ" w Oracle 10g PL/SQL

Przeczytałem, że Oracle 11g ma to jako nową funkcję, ale aktualizacja niestety nie jest opcją.

Czy istnieje alternatywa dla KONTYNUUJ w 10g? Nie sądzę, że praktyczne jest zrestrukturyzowanie logiki SP jako obejścia, ponieważ mam pętlę zewnętrzną, IF, a następnie zagnieżdżone IF, a następnie CONTINUE na końcu bloku instrukcji w tym IF.

Każda pomoc byłaby bardzo ceniona, na zdrowie.

Odpowiedz

52

Możesz symulować kontynuację używając goto and labels.

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 za brzydki sposób obejścia brzydkiego oświadczenia :) –

+2

Czasami musimy go wpisać i zakryć nasze nosy. :) – jop

+0

Możesz także użyć konstruktu, który idealnie naśladuje kontynuację. I bez dodawania żadnej wartości null :) Zobacz moją odpowiedź poniżej. – SRO

4

Czy możesz przekształcić IF w funkcję, powracając w odpowiednim punkcie (wcześniej, jeśli to konieczne). Następnie przepływ sterowania przejdzie w pętli we właściwym miejscu.

Czy to ma sens?

1

W Oracle podobny stwierdzenie zwany wyjścia, albo wyjście pętli lub funkcji/procedury (gdy nie ma pętli opuścić). Możesz dodać KIEDY, aby sprawdzić niektóre warunki.

Można przepisać powyższy przykład następująco:

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

To może nie wystarczyć, jeśli chcesz wyjść z głębi niektórych zagnieżdżonych pętli i logiki, ale jest o wiele jaśniejsze niż kilka GOTOS i NULL.

+1

Rozwiązanie EXIT tak naprawdę nie działałoby w tym przypadku, ponieważ przerwałoby to całą pętlę, a nie po prostu rozpoczynało się od następnej iteracji, jak zrobiłby to CONTINUE. Myślę, że będę musiał pójść z rozwiązaniem GOTO, kibicować wszystkim za sugestie! –

10

Chociaż jest to trochę skomplikowane i po prostu fałszywy, można użyć wyjątek ten sposób:

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

Niezupełnie eleganckie, ale proste :

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

w rzeczywistości, PL SQL ma coś do zastąpienia kontynuować. Wszystko co musisz zrobić, to dodać etykietę (nazwa) do pętli:

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

Trochę mniej brzydka niż GOTO, po której następuje linia NULL, ale działa. Dzięki! –

5

dla przyszłych poszukiwań, w Oracle 11g dodali continue oświadczenie, które mogą być używane tak:

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.