Подтвердить что ты не робот

Ключевое слово "CONTINUE" в Oracle 10g PL/SQL

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

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

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

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

4b9b3361

Ответ 1

Вы можете имитировать продолжение, используя goto и label.

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;

Ответ 2

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

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;

Ответ 3

Фактически, 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;

Ответ 4

Для будущих поисков в 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.

Ответ 6

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

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

Ответ 7

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

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

Ответ 8

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

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

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

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

Ответ 9

Это не совсем ответ на вопрос, но тем не менее стоит отметить:

Оператор continue в PL/SQL и во всех других языках программирования, которые используют его таким же образом, может быть легко истолкован неправильно.

Было бы намного мудрее, яснее и лаконичнее, если бы разработчики языка программирования вместо этого назвали ключевое слово skip.

Для меня, на фоне C, C++, Python,... всегда было понятно, что означает "продолжить".

Но без этого исторического фона вы могли бы прекратить интерпретировать этот код

for i in .. tab_xy.count loop
    CONTINUE WHEN some_condition(tab_xy(i));
    do_process(tab_xy(i));
end loop;

вот так:

Переберите записи таблицы tab_xy.

Продолжите, если запись выполняет some_condition, иначе проигнорируйте эту запись.

Do_process запись.

Это неверное толкование, но если вы представляете код PL/SQL как квитанцию о готовке и читаете его вслух, это может произойти.

Фактически это случилось с очень опытным коллегой по разработке только вчера.