Ключевое слово "CONTINUE" в Oracle 10g PL/SQL
Я переношу хранимую процедуру TSQL в PL/SQL и столкнулся с проблемой - отсутствие ключевого слова CONTINUE в Oracle 10g.
Я читал, что Oracle 11g имеет это как новую функцию, но обновление, к сожалению, не является вариантом.
Есть ли альтернатива CONTINUE в 10g? Я не считаю целесообразным реструктурировать логику SP как обход, потому что у меня есть внешний цикл, IF, затем вложенный IF, а затем CONTINUE в конце блока операторов внутри этого IF.
Любая помощь будет принята с благодарностью, приветствия.
Ответы
Ответ 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.
Ответ 5
Он недоступен в 10g, однако новая функция в 11G
Ответ 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 как квитанцию о готовке и читаете его вслух, это может произойти.
Фактически это случилось с очень опытным коллегой по разработке только вчера.