El lenguaje PL/SQL de Oracle posee desde sus comienzos una funcionalidad muy utilizada que es el iterador FOR..LOOP. El mismo permite en forma sencilla recorrer una serie de valores consecutivos dentro de un rango dado. Veamos un ejemplo de su funcionalidad:
BEGIN FOR NumVar IN 10 .. 12 LOOP dbms_output.put_line('Soy el numero ' || TO_CHAR(NumVar)); END LOOP; END; / Soy el numero 10 Soy el numero 11 Soy el numero 12 PL/SQL procedure successfully completed. SQL>
No es necesario declarar previamente la variable "NumVar" ni aclarar el incremento deseado (siempre es de a uno). Es posible incluir la palabra clave "REVERSE" antes del rango para que el mismo lo haga en orden reverso, pero hasta Oracle 21c no era posible hacer mucho mas:
BEGIN FOR NumVar IN REVERSE 10 .. 12 LOOP dbms_output.put_line('Soy el numero ' || TO_CHAR(NumVar)); END LOOP; END; / Soy el numero 12 Soy el numero 11 Soy el numero 10 PL/SQL procedure successfully completed. SQL>
Lo nuevo en Oracle 21c
Oracle 21c ofrece algunas opciones adicionales, las cuales vamos a analizar a continuación y en un segundo artículo.
Iteración de valor único
En Oracle 21c Podemos hacer iteraciones de un un solo valor, de la siguiente manera:
BEGIN FOR NumVar IN 20 LOOP dbms_output.put_line('Soy el numero ' || TO_CHAR(NumVar)); END LOOP; END; / Soy el numero 20 PL/SQL procedure successfully completed. SQL>
En si, esta no parece una opción muy interesante, pero lo que le suma utilidad es la posibilidad de usar la clausula REPEAT con la opción WHILE para definir una lógica adicional, como mostramos a continuación:
BEGIN FOR NumVar IN 2, REPEAT NumVar * 3 WHILE NumVar < 100 LOOP dbms_output.put_line('Soy el numero ' || TO_CHAR(NumVar)); END LOOP; END; / Soy el numero 2 Soy el numero 6 Soy el numero 18 Soy el numero 54 PL/SQL procedure successfully completed.
Iteraciones Múltiples
Esta opción nos permite definir varios rangos para iterar, de forma tal que la lógica que vamos a ejecutar la definimos en un solo lugar (en nuestro ejemplo, es un simple DBMS_OUTPUT) sin necesidad de crear multiples bloques de iteración:
BEGIN FOR NumVar IN 2 .. 4, REVERSE 6 .. 8, 15 .. 16 LOOP dbms_output.put_line('Soy el numero ' || TO_CHAR(NumVar)); END LOOP; END; / Soy el numero 2 Soy el numero 3 Soy el numero 4 Soy el numero 8 Soy el numero 7 Soy el numero 6 Soy el numero 15 Soy el numero 16 PL/SQL procedure successfully completed.
Iteraciones por rango con salto definido por el usuario
Esta opción nos permite controlar el incremento entre cada iteración (antes de Oracle 21c era si o si el valor 1), como vemos a continuación:
BEGIN FOR NumVar IN 2 .. 6 BY 2, REVERSE 2 .. 6 BY 2 LOOP dbms_output.put_line('Soy el numero ' || TO_CHAR(NumVar)); END LOOP; END; / Soy el numero 2 Soy el numero 4 Soy el numero 6 Soy el numero 6 Soy el numero 4 Soy el numero 2 PL/SQL procedure successfully completed.
Iteraciones por rango con salto decimal definido por el usuario
Si bien la sintaxis permitía el uso de valores decimales para los valores de inicio y fin del rango, estos eran redondeados a un valor enter en forma automática. Oracle 21c permite definir tanto rangos decimales (manteniendo los incrementos en 1) como también incrementos decimales, como podemos ver en los siguientes ejemplos.
En este ejemplo, el primer rango tiene comienzo y fin con decimales pero incremento entero:
BEGIN FOR NumVar NUMBER(4,1) IN 2.3 .. 4.3 LOOP dbms_output.put_line('Soy el numero ' || TO_CHAR(NumVar)); END LOOP; END; / Soy el numero 2.3 Soy el numero 3.3 Soy el numero 4.3 PL/SQL procedure successfully completed.
Este segundo ejemplo, tanto los valores de inicio / fin del rango como el incremento se define como valor decimal:
BEGIN FOR NumVar NUMBER(4,1) IN 2.3 .. 4.3 BY 0.4 LOOP dbms_output.put_line('Soy el numero ' || TO_CHAR(NumVar)); END LOOP; END; / Soy el numero 2.3 Soy el numero 2.7 Soy el numero 3.1 Soy el numero 3.5 Soy el numero 3.9 Soy el numero 4.3 PL/SQL procedure successfully completed.
Lo único que tenemos que tener en cuenta, es definir el tipo de datos de la variable (NumVar) que va a mantener los valores, con un tipo de datos apropiado, como se resalta en los ejemplos.
Salteando valores y deteniendo las iteraciones
La opción WHEN nos permite saltear valores no deseados, por ejemplo si queremos "procesar" solo los números pares en un rango en particular, podemos usar la siguiente sintaxis:
BEGIN FOR NumVar IN 3 .. 10 WHEN MOD(NumVar,2) = 0 LOOP dbms_output.put_line('Soy el numero ' || TO_CHAR(NumVar)); END LOOP; END; / Soy el numero 4 Soy el numero 6 Soy el numero 8 Soy el numero 10 PL/SQL procedure successfully completed.
Por otro lado, la opción WHILE (la cual vimos dentro del uso de REPEAT) nos permite definir una condición de salida que detendrá la ejecución del bloque, como podemos ver a continuación:
BEGIN FOR NumVar IN 4 .. 20 WHILE NumVar * NumVar < 100 LOOP dbms_output.put_line('Soy el numero ' || TO_CHAR(NumVar)); END LOOP; END; / Soy el numero 4 Soy el numero 5 Soy el numero 6 Soy el numero 7 Soy el numero 8 Soy el numero 9 PL/SQL procedure successfully completed.
Como podemos ver, al evaluar NumVar = 10, la operación NumVar * NumVar da como resultado 100, dejando de cumplir la condición definida en la cláusula WHILE, por lo que el valor 10 no se imprime y el bucle termina.
Lo que sigue
En el próximo artículo veremos en detalles otras mejorar al iterador FOR .. LOOP incluidas en Oracle 21c, que permiten usar el mismo con colecciones PL/SQL.
No hay comentarios.:
Publicar un comentario