BLOQUES ANONIMOS Y ESTRUCTURAS DE CONTROL

Bloques anónimos PL/SQL

Empezaremos con los bloques anónimos, caracterizados porque no tienen nombre y se suelen crear y ejecutar desde PL/SQL.
Todo bloque debe acabar en . para que sea almacenado en el buffer SQL. Una vez guardado lo podemos ejecutar con la orden “run”. También podemos guardarlo en un fichero con la siguiente orden:
save nombrefichero [replace]
El replace sólo lo pondremos si el fichero ya esta creado.
Para cargar y ejecutar este bloque anónimo guardado en fichero ejecutaremos la siguiente orden:
start nombrefichero
El start lo podemos cambiar por la @ y nos funcionará igualmente.
Pero también podemos cargarlo sin ejecutarlo con la orden “get” y luego ejecutarlo posteriormente con la orden “run”
Un ejemplo muy sencillo de bloque seria el que nos muestra en pantalla un nombre.
BEGIN
   DBMS_OUTPUT.PUT_LINE('nombre');
END;
.

Además en los bloques PL/SQL se pueden utilizar lo que llamamos variables de sustitución, que nos pedirán datos por pantalla antes de ejecutar el bloque. Estas variables tienen que ir antepuestas del & para que funcionen.
Un ejemplo seria un bloque que nos pide el DNI de un usuario y nos muestra su nombre.
DECLARE
   Vnom clientes.nombre%TYPE;
BEGIN
   select nombre into Vnom from clientes where NIF= '&V_nif';
   DBMS_OUTPUT.PUT_LINE (Vnom);
END;
.

Como veis es bastante sencillo, pero no tienen tanta funcionalidad como los procedimientos o funciones.

Procedimientos y funciones PL/SQL

Los procedimientos y funciones quedan almacenados en la base de datos a diferencia de los bloques anónimos que se almacenaban en el buffer.
Nota: Al quedar los bloques anónimos almacenados en el buffer, a no ser que se guardasen en ficheros, se perderían al limpiar el buffer, cosa que no ocurre con los procedimientos y funciones, que se almacenan en la propia base de datos.

Otra cosa que nos diferencia los bloques anónimos de los procedimientos o funciones es que en los procedimientos o funciones no se pueden utilizar variables de sustitución.
En cuanto a su construcción es la dada en el articulo Características de PL/SQL segunda parte  añadiendo al principio la siguiente secuencia “CREATE OR REPLACE” para crearlo, o modificarlo si ya existe.
Pasamos a escribir un procedimiento que nos muestre los datos de un usuario:
CREATE OR REPLACE PROCEDURE ver_usuario(nomusu VARCHAR2)
IS
   NIFusu   VARCHAR2(10);
   Domusu   VARCHAR2(10);
BEGIN
   select nif, domicilio into NIFusu,Domusu from usuario where nombre=nomusu;
   DBMS_OUTPUT.PUT_LINE('Nombre:'||nomusu|| 'NIF:' ||NIFusu|| 'Domicilio' ||Domusu);
EXCEPTION
   WHEN NO_DATA_FOUND THEN
      DBMS_OUTPUT.PUT_LINE('No hemos encontrado al usuario || nomusu);
END;
/

Si el compilador detecta errores nos saldrá un mensaje como este: “Procedimiento creado con errores de compilación”. Para ver estos errores tenemos la orden SHOW ERRORS.
Al tener almacenado el procedimiento en la base de datos, este puede ser llamado por cualquier usuario que tenga los permisos oportunos. Para invocar un procedimiento utilizamos la orden EXECUTE
Para invocar al procedimiento que hemos creado antes tendríamos que ejecutar la siguiente orden:
EXECUTE ver_usuario('Luis');
Pero también podemos invocarlo desde un bloque PL/SQL de ls siguiente forma:
BEGIN
   ver_usuario('Luis');
END;

Estructuras de Control

 Las estructuras de control presentes en PL/SQL son las comunes de los lenguajes de programación estructurados: IF, WHILE, FOR y LOOP. 


Control alternativo 
 El control para manejo de opciones es el IF, el cual tiene la siguiente sintaxis: 


 (1) 


 IF <condición> THEN

   Instrucciones;

   ...;

 END IF;

 (2)

 IF <condición> THEN

   Instrucciones;

   ...;

 ELSE

   Instrucciones;

   ...;

 END IF;

 (3)

 IF <condición> THEN

   Instrucciones;

   ...;

 ELSIF <condición2> THEN

   Instrucciones;

   ...;

 ELSIF <condición3> THEN

   Instrucciones;

   ...;

 ELSE

   Instrucciones;

   ...;

 END IF;



 Vea el siguiente ejemplo: 


 PROCEDURE init_recip_list IS
  recipient_num NUMBER;
  i BINARY_INTEGER;
  j BINARY_INTEGER := 1;
  k BINARY_INTEGER;
BEGIN
  FOR i in 1..10 LOOP
   IF i = 1 THEN
     j := j + 1;
   ELSE
     FOR k in 1..j LOOP
       IF k = i THEN
         j := j + 2;
       ELSIF k = j THEN
         j := j + 1;
       END IF; 

     END LOOP;
   END IF;
  END LOOP;
END;

 Otro control interactivo es el EXIT-WHEN, el cual permite combinarse con el LOOP. 


 OPEN c_line_item;
LOOP
  FETCH c_line_item INTO rec_info;
  EXIT WHEN (c_line_item%NOTFOUND) OR (c_line_item%NOTFOUND is NULL);
END LOOP;
CLOSE c_line_item;

Control repetitivo 
 Pueden tenerse varias condiciones para los ciclos. 


WHILE 
Este verifica una condición, que mientras sea verdadera se mantiene en el ciclo. La sintaxis es la siguiente: 

 WHILE <condición> LOOP
  Instrucciones;
  ...;
END LOOP;

 FOR numérico 
Utilice este ciclo para realizar iteraciones sobre un rango de números. 

 FOR <variable> IN <mínimo>..<máximo> LOOP
  Instrucciones;
  ...;
END LOOP;

 
FOR con cursores 
Este es un tipo que combina el control de cursores y el uso de ciclos para recorrerlo. Acá no hace falta abrir y cerrar el cursor directamente, sino que el FOR se encarga de ello. 

 CURSOR c_line_item IS
(estatuto SQL)
BEGIN
  FOR rec_info IN c_line_item LOOP
   Intrucciones;
  END LOOP;
END;

 Véase que uno declara el rec_info, que para los efectos es un registro de tipo c_line_item (%ROWTYPE), el cual no es necesario declararlo, sino que se crean como una variable local al FOR. Por último, el FOR realiza de forma implícita el FETCH sobre el rec_info.
 

LOOP 
Utilice el LOOP para realizar procesamiento interactivo basado en escogencias lógicas. La sintaxis común es 

 LOOP 

  Instrucciones;
  ...;
  EXIT WHEN <condición>;
  Instrucciones;
  ...;
END LOOP;