Ключевое слово "ПРОДОЛЖЕНИЕ" в Oracle 10g PL/SQL
Я переносил хранимую процедуру TSQL в PL/SQL и столкнулся с проблемой - отсутствием ключевого слова CONTINUE в Oracle 10g.
Я читал, что Oracle 11g имеет это как новую функцию, но обновление, к сожалению, не вариант.
Есть ли альтернатива ПРОДОЛЖИТЬ в 10g? Я не верю, что практично реструктурировать логику SP как обходного пути, потому что у меня есть внешний цикл, IF, затем вложенный IF, затем CONTINUE в конце блока операторов в этом IF.
Любая помощь будет принята с благодарностью, ура.
8 ответов
Вы можете смоделировать продолжение, используя goto и метки.
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;
Хотя это немного сложно и просто подделка, вы можете использовать исключение следующим образом:
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;
На самом деле PL PL имеет что-то, чтобы заменить 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;
Для будущих поисков, в оракуле 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.
Можете ли вы реорганизовать IF в функцию, вернувшись в соответствующую точку (при необходимости, раньше). Тогда поток управления подхватит в петле в нужном месте.
Имеет ли это смысл?
Не совсем элегантно, но просто:
DECLARE
done BOOLEAN;
BEGIN
FOR i IN 1..50 LOOP
IF done THEN
NULL;
ELSE
<do loop stuff>;
END IF;
END LOOP;
END;
В Oracle есть похожая инструкция EXIT, которая либо выходит из цикла, либо из функции / процедуры (если нет цикла для выхода из). Вы можете добавить КОГДА для проверки некоторых условий.
Вы можете переписать приведенный выше пример следующим образом:
DECLARE
done BOOLEAN;
BEGIN
FOR i IN 1..50 LOOP
EXIT WHEN done;
END LOOP;
END;
Этого может быть недостаточно, если вы хотите выйти из глубины некоторых вложенных циклов и логики, но это намного понятнее, чем пара GOTO и NULL.
Это не совсем ответ на вопрос, но, тем не менее, стоит отметить:
В 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 как своего рода рецепт приготовления пищи и прочитаете его вслух, это может произойти.
На самом деле это случилось с очень опытным сотрудником по разработке буквально вчера.