Capítulo 4 - Sentencias de Control

Ahora complicaremos un poco más las cosas. Hasta el momento sólo hemos visto manejo de variables, operaciones matemáticas y la declaración de un script PL/SQL básico.

En éste capítulo veremos el uso de sentencias de control. Las sentencias de control permiten cambiar el flujo de ejecución las instrucciones de nuestro código PL/SQL, de ésta manera se puede indicar la ejecución de un bloque de instrucciones cuando se cumpla una condición o simplemente hacer que se repita en tiempo de ejecución.

En PL/SQL tenemos grupos de sentencias de control:

  • Condicional
  • Iterativo
  • Secuencial

Condicional

La estructura condicional está representada por las sentencias IF y CASE.

IF-THEN-ELSE(SI-ENTONCES-CASO CONTRARIO)

Ésta sentencia permite la ejecución de una o varias líneas de código según una condición. La condición se especifica en la cláusula IF, en caso de que la condición sea verdadera se ejecuta el bloque de código especificado bajo la cláusula THEN, en caso contrario se ejecuta el bloque de código especificado en la cláusula ELSE. La claúsula ELSE es opcional

Veamos un ejemplo:

DECLARE
/*Para poder ver la utilidad de éste script
basta con cambiar los valores de las variables
V_A y V_B según queramos. */
V_A NUMBER := 30;
V_B NUMBER := 10;

BEGIN
  /*En caso de que la variable V_A sea mayor
   se mostrará un mensaje*/
  IF V_A > V_B THEN
    dbms_output.put_line('V_A es mayor');
  END IF;
END;
V_A es mayor
El operador > (mayor que) permite realizar una comparación lógica entre 2 expresiones, en este caso, 2 variables. Así como existe el operador > (mayor que) existen los operadores <(menor que), = (igual que), <>(diferente que), etc. Éstos operadores son operadores de comparación y fueron tratados en el anterior capítulo.

La condición para la sentencia IF del ejemplo anterior, está dada por la comparación V_A > V_B, en caso de que el valor de V_A sea mayor que el de V_B se mostrará el mensaje "V_A es mayor", en caso de que V_B sea mayor o ambos iguales no se mostrará nada.

Ahora veamos el uso de la cláusula ELSE:

DECLARE
/*Para poder ver la utilidad de éste script
basta con cambiar los valores de las variables
V_A y V_B según queramos. */
V_A NUMBER := 30;
V_B NUMBER := 30;
BEGIN
  /*En caso de que la variable V_A sea mayor
   se mostrará un mensaje*/
  IF V_A > V_B THEN
    dbms_output.put_line('V_A es mayor');
  ELSE
    dbms_output.put_line('V_B es mayor o igual que V_A');
  END IF;
END;
V_B es mayor o igual que V_A

Para el ejemplo anterior, se ha adicionado la cláusula ELSE, la cual se ejecutará cuando la variable V_A no sea mayor que la variable V_B. Puedes probar cambiando los valores de las variables a tu gusto para ver cómo se se ejecutan las instrucciones de sólo una de las cláusulas(THEN o ELSE).

CASE(CASO)

La sentencia CASE permite evaluar diferentes opciones, por cada opción se realiza una instrucción específica. Veamos un ejemplo:

DECLARE
V_TIPO_TRABAJADOR VARCHAR2(2) := 'AP';
V_SALARIO         NUMBER;
BEGIN

  CASE
    WHEN V_TIPO_TRABAJADOR = 'AP' THEN
      V_SALARIO := 1500;
    WHEN V_TIPO_TRABAJADOR = 'AS' THEN
      V_SALARIO := 2300;
    WHEN V_TIPO_TRABAJADOR = 'JP' THEN
      V_SALARIO := 5000;
  END CASE;

  DBMS_OUTPUT.PUT_LINE('El salario de un ' || V_TIPO_TRABAJADOR 
                       || ' es ' || V_SALARIO);
END;
El salario de un AP es 1500

También se puede usar la sentencia CASE de manera simple para realizar la asignación de un valor según la evaluación de una variable por diferentes casos:

DECLARE
V_TIPO_TRABAJADOR VARCHAR2(2) := 'AP';
V_SALARIO         NUMBER;
BEGIN

  V_SALARIO:= CASE V_TIPO_TRABAJADOR
                WHEN 'AP' THEN   1500
                WHEN 'AS' THEN   2300
                WHEN 'JP' THEN   5000
              END;
  
  DBMS_OUTPUT.PUT_LINE('El salario de un ' || V_TIPO_TRABAJADOR 
                       || ' es ' || V_SALARIO);
END;
El salario de un AP es 1500

Finalmente, podemos hacer uso de la cláusula ELSE en caso de que ninguna de las opciones definidas en WHEN sea seleccionada:

DECLARE
V_TIPO_TRABAJADOR VARCHAR2(2) := 'AR';
V_SALARIO         NUMBER;
V_TIENE_SALARIO   BOOLEAN;
BEGIN

  CASE
    WHEN V_TIPO_TRABAJADOR = 'AP' THEN
      V_SALARIO := 1500;
      V_TIENE_SALARIO := TRUE;
    WHEN V_TIPO_TRABAJADOR = 'AS' THEN
      V_SALARIO := 2300;
       V_TIENE_SALARIO := TRUE;
    WHEN V_TIPO_TRABAJADOR = 'JP' THEN
      V_SALARIO := 5000;
      V_TIENE_SALARIO := TRUE;
    ELSE
      V_TIENE_SALARIO := FALSE;
  END CASE;

  IF V_TIENE_SALARIO THEN
    DBMS_OUTPUT.PUT_LINE('El salario de un ' || V_TIPO_TRABAJADOR 
                         || ' es ' || V_SALARIO);
  ELSE
    DBMS_OUTPUT.PUT_LINE(V_TIPO_TRABAJADOR 
                         || ' no tiene un salario definido');
  END IF;
END;
AR no tiene un salario definido

Iteravito

Las sentencias iterativas permiten ejecutar varias instrucciones múltiples veces. A éstas sentencias también se les conoce por el nombre de bucles repetitivos.

FOR-LOOP

La sentencia FOR-LOOP permite especificar un rango de números enteros, finalmente ejecuta una secuencia de instrucciones para cada número entero dentro de la lista de números.

Veámos un ejemplo:

BEGIN
  FOR i IN 1..8 LOOP
    DBMS_OUTPUT.PUT_LINE('El número de ésta iteracción es:' || i);
  END LOOP;
END;
El número de ésta iteracción es:1
El número de ésta iteracción es:2
El número de ésta iteracción es:3
El número de ésta iteracción es:4
El número de ésta iteracción es:5
El número de ésta iteracción es:6
El número de ésta iteracción es:7
El número de ésta iteracción es:8

En el ejemplo anterior, sólo existe una instrucción para imprimir un mensaje en la sentencia LOOP, pero sin embargo en la salida el mensaje se repite 8 veces con los números del 1 al 8. En la cláusula IN la expresión 1..8 genera una lista de números, para éste caso , del 1 al 8.

Probemos ahora generando la tabla de multiplicar del 7 del 1 al 12:

BEGIN
  FOR i IN 1..12 LOOP
    DBMS_OUTPUT.PUT_LINE('7*' || i || '='|| (7*i));
  END LOOP;
END;
7*1=7
7*2=14
7*3=21
7*4=28
7*5=35
7*6=42
7*7=49
7*8=56
7*9=63
7*10=70
7*11=77
7*12=84

WHILE-LOOP

La sentencia de control WHILE LOOP, al igual que FOR-LOOP, permite la ejecución de una o varias instrucciones. A diferencia de la sentencia FOR-LOOP, en WHILE-LOOP la ejecución se define a partir de una condición. Veamos un ejemplo:

DECLARE
  V_NUM NUMBER := 1;
BEGIN
  WHILE V_NUM <= 13 LOOP
    DBMS_OUTPUT.PUT_LINE('El valor V_NUM es :' || V_NUM);
    V_NUM := V_NUM + 2.1;
  END LOOP;
END;
El valor V_NUM es :1
El valor V_NUM es :3,1
El valor V_NUM es :5,2
El valor V_NUM es :7,3
El valor V_NUM es :9,4
El valor V_NUM es :11,5

En el ejemplo anterior, al igual que en la sentencia FOR-LOOP, el mensaje "El valor de V_NUM es ..." se repite varias veces, pero ésta vez la variable V_NUM se ve incrementada en 2.1 cada vez que la sentencia WHILE-LOOP se ejecuta. En la cláusula WHILE, mientras la condición V_NUM <= 13 es verdadera se ejecutará el código dentro de la cláusula LOOP. Finalmente debido al incremento realizado en la línea 6 (V_NUM := V_NUM + 2.1) el código sólo se repetirá 6 veces.

LOOP

La sentencia LOOP permite ejecutar un bloque de código de manera infinita, a diferencia de las otras sentencias iterativas, en la sentencia LOOP se debe utilizar la cláusula EXIT WHEN para colocar una condición para terminar el bucle:

DECLARE
  V_TOTAL    NUMBER := 0;
  V_CONTADOR NUMBER := 0;
BEGIN
  LOOP
    V_CONTADOR := V_CONTADOR + 1;
    V_TOTAL := V_TOTAL + V_CONTADOR;
    DBMS_OUTPUT.PUT_LINE('Valor de V_TOTAL:' || V_TOTAL);
    EXIT WHEN V_TOTAL > 20;
  END LOOP;
END;
Valor de V_TOTAL:1
Valor de V_TOTAL:3
Valor de V_TOTAL:6
Valor de V_TOTAL:10
Valor de V_TOTAL:15
Valor de V_TOTAL:21

En el ejemplo anterior, la sentencia LOOP terminará cuando el valor de la variables V_TOTAL sea mayor a 20.

Secuencial

La sentencia GOTO permite cambiar la línea secuencial de la ejecución hacia una etiqueta. Las etiquetas son marcadas con los símbolos << y >>. Para ir dirigir la ejecución hacia una etiqueta simplemente hay que usar la sentencia GOTO:

DECLARE
  V_TOTAL    NUMBER(9) := 0;
  V_CONTADOR NUMBER(6) := 0;
BEGIN
  
  <<calcular>>
  V_CONTADOR := V_CONTADOR + 1;
  V_TOTAL := V_TOTAL + V_CONTADOR;
  
  IF V_TOTAL <= 20 THEN
    DBMS_OUTPUT.PUT_LINE('Valor de V_TOTAL:' || V_TOTAL);
    GOTO calcular;
  END IF;
END;
Valor de V_TOTAL:1
Valor de V_TOTAL:3
Valor de V_TOTAL:6
Valor de V_TOTAL:10
Valor de V_TOTAL:15


En el ejemplo anterior, la sentencia GOTO redireccionará la ejecución hacia la línea 6 mientras el valor de V_TOTAL sea menor a 20.

Tecnologias: 
Tipo de Recurso: