2008-10-07 5 views
33

Я переношу хранимую процедуру TSQL в PL/SQL и столкнулся с проблемой - отсутствие ключевого слова CONTINUE в Oracle 10g.ключевое слово «CONTINUE» в Oracle 10g PL/SQL

Я читал, что Oracle 11g имеет это как новую функцию, но, к сожалению, обновление не является вариантом.

Есть ли альтернатива CONTINUE в 10g? Я не считаю целесообразным реструктурировать логику SP как обход, потому что у меня есть внешний цикл, IF, затем вложенный IF, а затем CONTINUE в конце блока операторов внутри этого IF.

Любая помощь будет принята с благодарностью, приветствия.

ответ

52

Вы можете имитировать продолжение, используя 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 для уродливого обходного пути, чтобы справиться с уродливым заявлением :) –

+2

Иногда нам просто нужно вводить его и покрывать наши носы потом. :) – jop

+0

Вы также можете использовать конструкцию, которая имитирует продолжение. И без добавления нулевого значения. См. Мой ответ ниже. – SRO

4

Можете ли вы преобразовать IFs в функцию, возвращаясь в соответствующую точку (если необходимо раньше). Затем поток управления будет подниматься в петле в нужном месте.

Это имеет смысл?

1

В Oracle есть аналогичное утверждение называется EXIT, что либо выходит из цикла или функции/процедуры (если нет петли для выхода из). Вы можете добавить КОГДА, чтобы проверить какое-то условие.

Вы можете переписать приведенный выше пример следующим образом:

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

Это не может быть достаточно, если вы хотите, чтобы выйти из глубины некоторых вложенных циклов и логики, но это гораздо яснее, чем пару GOTOS и Значения NULL.

+1

Решение EXIT на самом деле не работает в этом случае, потому что оно завершает весь цикл, а не только на следующей итерации, как это делает CONTINUE. Я думаю, мне придется пойти с решением GOTO, приветствую всех за ваши предложения! –

10

Хотя это немного сложно и просто подделка, вы можете использовать исключение, таким образом:

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

Не совсем элегантно, но просто :

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

Фактически, PL SQL имеет что-то, что заменит CONTINUE. Все, что вам нужно сделать, это добавить метку (имя) к петле:

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

Немного менее уродливый, чем GOTO, за которым следует линия NULL, но она работает. Благодаря! –

5

для будущих поисков, в Oracle 11g они добавили continue заявление, которое может быть использовано как это:

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. 
Смежные вопросы