2008-10-07 20 views
33

Estoy migrando un procedimiento almacenado TSQL a PL/SQL y he encontrado un problema: la falta de una palabra clave CONTINUAR en Oracle 10g.palabra clave 'CONTINUAR' en Oracle 10g PL/SQL

He leído que Oracle 11g tiene esto como una nueva característica, pero actualizar no es una opción desafortunadamente.

¿Hay alguna alternativa para 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 CONTINUAR al final de un bloque de instrucciones dentro de ese IF.

Cualquier ayuda sería muy apreciada, saludos.

Respuesta

52

Puede simular un continuar usando goto and labels.

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; 
+4

+1 por una solución fea para manejar una declaración fea :) –

+2

A veces, simplemente tenemos que escribirlo y tapar nuestras narices después. :) – jop

+0

También puede usar una construcción que imita un continuar perfectamente. Y sin agregar ningún nulo :) Vea mi respuesta a continuación. – SRO

4

Puede refactorizar los IF en una función, volviendo al punto apropiado (temprano si es necesario). Luego, el flujo de control se recuperará en el bucle en el lugar correcto.

¿Tiene sentido?

1

En Oracle hay una declaración similar llamada de salida que o bien sale de un bucle o una función/procedimiento (si no hay bucle para salir de). Puede agregar un CUÁNDO para verificar alguna condición.

Se podría reescribir 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 algunos bucles anidados y la lógica, pero es mucho más claro que un par de GOTOs y NULLs

+1

La solución EXIT no funcionaría realmente en este caso, porque terminaría todo el ciclo, en lugar de solo comenzar en la siguiente iteración como lo haría CONTINUAR. ¡Creo que tendré que ir con la solución GOTO y alentar a todos por sus sugerencias! –

5

No está disponible en 10g, sin embargo se trata de una new feature en 11G

10

A pesar de que es un poco complejo y sólo una falsa, puede utilizar 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; 
2

No es exactamente elegante, pero sencillo :

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

De hecho, PL SQL tiene algo que reemplazar CONTINUAR. Todo lo que tiene que hacer es añadir 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; 
+1

Solo un poco menos feo que el GOTO seguido de una línea NULL, pero funciona. ¡Gracias! –

5

Para búsquedas en el futuro, en Oracle 11g, agregaron una declaración continue, que puede ser utilizado como esto:

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. 
Cuestiones relacionadas