Palabra clave 'CONTINUAR' en Oracle 10g PL / SQL
Pregunta
Estoy migrando un procedimiento almacenado de TSQL a PL / SQL y he encontrado un problema: la falta de una palabra clave CONTINUE en Oracle 10g.
He leído que Oracle 11g tiene esto como una nueva característica, pero la actualización no es una opción, lamentablemente.
¿Hay alguna alternativa a CONTINUAR en 10g? No creo que sea práctico reestructurar la lógica del SP como una solución alternativa, porque tengo un bucle externo, un IF, luego un IF anidado, luego el CONTINUO al final de un bloque de declaración dentro de ese IF.
Cualquier ayuda sería muy apreciada, saludos.
Solución
Puedes simular una continuación usando goto y etiquetas .
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;
Otros consejos
Aunque es un poco complejo y solo es falso, puedes usar la excepción de esta manera:
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;
De hecho, PL SQL tiene algo que reemplazar CONTINUAR. Todo lo que tienes que hacer es agregar una etiqueta (un nombre) al bucle:
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;
Para búsquedas futuras, en oracle 11g agregaron una declaración continue
, que se puede usar de esta manera:
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.
No está disponible en 10g, sin embargo, es una nueva característica en 11G
¿Puede refactorizar los IF en una función, regresando al punto apropiado (temprano si es necesario). Luego, el flujo de control se recuperará en el bucle en el lugar correcto.
¿Eso tiene sentido?
No es exactamente elegante, pero simple:
DECLARE
done BOOLEAN;
BEGIN
FOR i IN 1..50 LOOP
IF done THEN
NULL;
ELSE
<do loop stuff>;
END IF;
END LOOP;
END;
En Oracle hay una declaración similar llamada EXIT que sale de un bucle o de una función / procedimiento (si no hay ningún bucle para salir). Puede agregar un CUANDO para verificar alguna condición.
Puede volver a escribir el ejemplo anterior de la siguiente manera:
DECLARE
done BOOLEAN;
BEGIN
FOR i IN 1..50 LOOP
EXIT WHEN done;
END LOOP;
END;
Esto puede no ser suficiente si desea salir desde el fondo de algunos bucles y lógica anidados, pero es mucho más claro que un par de GOTO y NULL.