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.

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top