domingo, 30 de octubre de 2011

Simulación de la sentencia continue en PL/SQL

En ocasiones se nos da la circunstancia de que dentro de bucle nos pude interesar ejecutar cierta parte del código siempre que se cumpla una condición, no haciendo nada más en esa iteración en caso contrario. Lo normal sería hacerlo más o menos así (en todos estos suspuestos se sobreentiende que tenemos al menos una condición de salida para el bucle):

(...)
LOOP
    (...)
    IF test THEN
        -- Código a ejecutar
        (...)
    END IF;
END LOOP;

(...)


La cosa se complica si tenemos varios de esos tests:

(...)
LOOP
    (...)
    IF test1 THEN
        -- Código a ejecutar test1
        (...)

        IF test2 THEN
            -- Código a ejecutar test2
            (...)
        END IF;

        (...)
    END IF;
END LOOP;
(...)


De aquí se puede llegar a la conclusión de que si son muchas las condiciones a comprobar, el programa puede llegar a ser bastante ilegible puesto que se hacen muchos anidamientos de sentencias IF.


En el lenguaje C existe una instrucción que salta al final del bucle para volver a ejecutar la siguiente iteración: es la instrucción continue. Con esta sentencia podríamos simplificar bastante nuestro programa.

En PL/SQL no tenemos esa instrucción pero se puede simular mediante las llamadas excepciones de usuario. Estas excepciones se declaran en la sección de variables (aunque realmente no lo son, sólo son excepciones) y pueden elevarse con la sentencia RAISE para ser tratadas en un bloque de excepciones. Lo único que hay que hacer es codificar un manejador de excepciones para nuestra excepción y colocarlo justo antes de la finalización del bucle. Si el manejador no hace nada (con la instrucción NULL) conseguiremos el mismo efecto que continue. Sería algo así como esto:

DECLARE
    siguiente_iteracion EXCEPTION;

BEGIN
    (...)
    LOOP
        BEGIN
            (...)
            IF NOT test1 THEN
                RAISE siguiente_iteracion;
            END IF;

            -- Código a ejecutar tras test1
            (...)

            IF NOT test2 THEN
                RAISE siguiente_iteracion;
            END IF;

            -- Código a ejecutar tras test2
            (...)

           IF NOT test3 THEN
               RAISE siguiente_iteracion;
           END IF;

           -- Código a ejecutar tras test3
           (...)

        EXCEPTION WHEN siguiente_iteracion THEN
            NULL;
        END;
    END LOOP;
    (...)
END;

No hay comentarios:

Publicar un comentario