Está en la página 1de 9

Bloques PL/SQL

Un programa de PL/SQL está compuesto por bloques. Un programa está compuesto


como mínimo de un bloque.

Los bloques de PL/SQL pueden ser de los siguientes tipos:

 Bloques anónimos: es el bloque más básico en PL/SQL. Son instrucciones del lenguaje
que se pueden teclear directamente en la consola de SQL y que son ejecutadas tras
introducir el carácter “/” (barra inclinada). Los bloques anónimos no se guardan ni
pertenecen a la definición de la base de datos. Si se necesita volver a ejecutarlo hay
que introducir el código de nuevo.
 Subprogramas: son los procedimientos y funciones. Representan un concepto análogo
a los métodos en programación orientada a objetos y su código puede ser usado
repetidas veces con solo llamar al subprograma por medio de su nombre. Más
adelante se verán con más detalle.

Estructura de un bloque

Los bloques PL/SQL presentan una estructura específica compuesta de tres partes
bien diferenciadas:

 La sección declarativa en donde se declaran todas las constantes y variables que se van
a utilizar en la ejecución del bloque.
 La sección de ejecución que incluye las instrucciones a ejecutar en el bloque PL/SQL.
 La sección de excepciones en donde se definen los manejadores de errores que
soportará el bloque PL/SQL.

Cada una de las partes anteriores se delimita por una palabra reservada, de modo
que un bloque PL/SQL se puede representar como sigue:

[ declare | is | as ]
/*Parte declarativa*/
begin
/*Parte de ejecucion*/
[ exception ]
/*Parte de excepciones*/
end;

De las anteriores partes, únicamente la sección de ejecución es obligatoria, que


quedaría delimitada entre las cláusulas BEGIN y END. Veamos un ejemplo de bloque
PL/SQL muy genérico. Se trata de un bloque anónimo, es decir, no lo identifica ningún
nombre. Los bloques anónimos identifican su parte declarativa con la palabra
reservada DECLARE.
DECLARE
/*Parte declarativa*/
nombre_variable DATE;
BEGIN
/*Parte de ejecución
* Este código asigna el valor de la columna "fechaEntrada" de la
tabla “tabla1” a la variable identificada por "nombre_variable" */
SELECT fechaEntrada
INTO nombre_variable
FROM tabla1;

EXCEPTION
/*Parte de excepciones*/
WHEN OTHERS THEN
dbms_output.put_line('Se ha producido un error');
END;

A continuación, vamos a ver cada una de estas secciones.

Sección de declaración de variables

En esta parte se declaran las variables que va a necesitar nuestro programa. Una
variable se declara asignándole un nombre o "identificador" seguido del tipo de valor
que puede contener. También se declaran cursores, de gran utilidad para la consulta de
datos, y excepciones definidas por el usuario. También podemos especificar si se trata
de una constante, si puede contener valor nulo y asignar un valor inicial.

La sintaxis genérica para la declaración de constantes y variables es:

nombre_variable [CONSTA NT] <tipo_dato> [NOT NULL][:= | DEFAULT | Expresion];

donde:

tipo_dato: es el tipo de dato que va a poder almacenar la variable, este puede ser
cualquiera de los tipos soportados por ORACLE, es
decir, NUMBER , DATE , CHAR , VARCHAR, VARCHAR2, BOOLEAN, etc. Además, para
algunos tipos de datos (NUMBER y VARCHAR) podemos especificar la longitud.

La cláusula CONSTANT indica la definición de una constante cuyo valor no puede ser
modificado. Se debe incluir la inicialización de la constante en su declaración.

La cláusula NOT NULL impide que a una variable se le asigne el valor nulo, y por tanto
debe inicializarse a un valor diferente de NULL.

Las variables que no son inicializadas toman el valor inicial NULL.

La inicialización puede incluir cualquier expresión legal de PL/SQL, que lógicamente debe
corresponder con el tipo del identificador definido.
Los tipos escalares incluyen los definidos en SQL más los tipos VARCHAR y BOOLEAN.
Este último puede tomar los valores TRUE, FALSE y NULL, y se suele utilizar para
almacenar el resultado de alguna operación lógica. VARCHAR es un sinónimo de CHAR.

También es posible definir el tipo de una variable o constante, dependiendo del tipo de
otro identificador previamente declarado, mediante la utilización de los
atributos %TYPE y %ROWTYPE. Por ejemplo, con %TYPE se puede hacer que una
variable sea del mismo tipo que un campo de una tabla de la base de datos. Esto tiene
la ventaja de que, si en un futuro se cambia el tipo del campo, todas las variables que
hayan sido declaradas así se cambiarán automáticamente y el código seguirá
funcionando.

Mediante %ROWTYPE se pueden declarar variables que hagan referencia a toda una fila
completa de la tabla, es decir, a una tupla o registro utilizando cursores.

Ejemplos de declaración de constante y variables:

DECLARE
-- Declaro una constante identificada por PI y se le asigna el valor 3.1416
PI CONSTANT NUMBER(5,4):= 3.1416;

-- Declaro una variable de tipo fecha y no la inicializo


fechaVenta DATE;

-- Declaro una variable numérica y la inicializo


codigoInforme NUMBER (3) NOT NULL := 353;

-- Declaro una variable carácter y la inicializo


nombreProducto VARCHAR(20) := ’Tornado25’;

/* Declaro una variable llamada importeVenta1 del mismo tipo que el campo Importe de la
tabla Pedidos */
importeVenta1 Pedidos.Importe%TYPE;

/* Declaro una variable llamada regPedido del mismo tipo que toda una fila (un registro) de la
tabla Pedidos */
regPedidos Pedidos %ROWTYPE;

Conviene señalar que, cuando tenemos una variable de tipo registro, podemos
referirnos a cada uno de los campos usando el nombre de la variable y del campo
separados por un punto, exactamente igual que hacemos con las columnas de una tabla,
así:

regPedidos.Importe

hace referencia al campo Importe de su contenido, que es toda una fila de la tabla
Pedidos.
Estructura de un bloque anónimo.

DECLARE
/* Se declara la variable de tipo VARCHAR2(15) identificada por v_location y se le asigna
el valor "Granada"*/

v_location VARCHAR2(15) := ’Granada’;

/*Se declara la constante de tipo NUMBER identificada por PI y se le asigna


el valor 3.1416*/
PI CONSTA NT NUMBER := 3.1416;

/*Se declara la variable del mismo tipo que tenga el campo nombre de la tabla
tabla_empleados identificada por v_nombre y no se le asigna ningún valor */
v_nombre tabla_empleados.nombre %TYPE;

/*Se declara la variable del tipo registro correspondiente a un supuesto cursor,


llamado miCursor, identificada por reg_datos*/
reg_datos miCursor%ROWTYPE;

BEGIN
/*Parte de ejecución*/
EXCEPTION
/*Parte de excepciones*/
END;

/ /*Indica que se ejecuten las sentencias del bloque*/

Estructura de un subprograma:

CREATE PROCEDURE simple_procedure IS


/* Se declara la variable de tipo VARCHAR2(15) identificada por v location y se le asigna
el valor "Granada"*/

v_location VARCHAR2(15) := ’Granada’;

/*Se declara la constante de tipo NUMBER identificada por PI y se le asigna


el valor 3.1416*/
PI CONSTA NT NUMBER := 3.1416;

/*Se declara la variable del mismo tipo que tenga el campo nombre de la tabla
tabla_empleados identificada por v_nombre y no se le asigna ningún valor */
v_nombre tabla_empleados.nombre %TYPE;

/*Se declara la variable del tipo registro correspondiente a un supuesto cursor,


llamado miCursor, identificada por reg_datos*/
reg_datos miCursor%ROWTYPE;

BEGIN
/*Parte de ejecución*/
EXCEPTION
/*Parte de excepciones*/
END;
Entrada y salida para depuración

PL/SQL no está pensado para interactuar directamente con un usuario final, por lo que
carece de un buen elenco de instrucciones especializadas para este fin. No obstante sí
permite mostrar información en pantalla o pedirla por teclado para asignar valores a
variable, por ejemplo.

La salida

Para que funcione es necesario activar al principio de la sesión la variable


SERVEROUTPUT de Oracle, una vez hecho esto (solo es necesario hacerlo una vez por
sesión, no por cada línea que queramos ver en pantalla) se puede usar la salida por
pantalla:

SET SERVEROUTPUT ON

Con la salida activada ya podemos usar el método predefinido de Oracle para mostrar
información en la pantalla con esta sintaxis:

dbms_output.put_line (Cadena de salida);

Podemos mostrar texto, el valor de una variable, constantes, el resultado de funciones


y concatenar las variaciones anteriores usando el operador “||”.

Ejemplos:

dbms_output.put_line(‘Buenas tardes’);
-- Muestra texto

dbms_output.put_line(nombreProducto);
-- Muestra el contenido de esa variable

dbms_output.put_line(‘El producto elegido es: ’ || nombreProducto);


-- Muestra texto concatenado al contenido de una variable

dbms_output.put_line(‘El mayor es: ’ || mayor(3,7));


-- Muestra texto concatenado al resultado de una función

dbms_output.put_line(‘La fecha de hoy es: ’|| sysdate);


-- Muestra texto y le concatena el valor de una función de Oracle

La entrada

Para leer valores de teclado hay que hacer una asignación a una variable y poner el
símbolo & seguido de una cadena de caracteres que se mostrará al pedir la entrada.
Esta cadena debe ir sin espacios en blanco, se recomienda usar guiones bajos para
separar las palabras y que no sea muy larga.
La sintaxis es:

nombreVariable := &Texto_a_mostrar_para_pedir_el _valor_de_entrada;

Ejemplo de uso de entrada y salida:

SET SERVEROUTPUT ON

-- Este código pide una base, una altura y halla el área de un


triangulo

DECLARE
altura INT;
base INT;

BEGIN
altura :=&INTRODUCE_EL_VALOR_DE_LA_ALTURA;
base :=&INTRODUCE_EL_VALOR_DE_LA_BASE;
DBMS_OUTPUT_PUTLINE(‘Un triángulo de base: ‘||base||’ y de altura:
‘||altura||’ tiene un área de: ‘||base*altura/2);

END;

Estructuras de control en PL/SQL

Estructuras de control de flujo

En PL/SQL disponemos de la estructura condicional IF. Su sintaxis se muestra a


continuación:

IF (expresion) THEN
-- Instrucciones
ELSIF (expresion) THEN
-- Instrucciones
ELSE
-- Instrucciones
END IF;

Un aspecto a tener en cuenta es que la instrucción condicional anidada es ELSIF y


no "ELSEIF".

Sentencia CASE

Es similar a la sentencia switch de Java, evalúa cada condición hasta encontrar alguna
que se cumpla, es decir, es una selección múltiple. La sintaxis es:
CASE [expression]
WHEN (condicion1|valor1) THEN
-- bloqueInstrucciones1
WHEN (condicion2|valor2) THEN
-- bloqueInstrucciones2
……
ELSE
-- bloqueInstruccionesPorDefecto
END CASE;

La sentencia CASE aplicada la podemos observar aquí en estos dos ejemplos:

CASE
WHEN anticuerposCovid >1000 THEN
DBMS_OUTPUT.PUT_LINE(‘Positivo’);
WHEN anticuerposCovid <10 THEN
DBMS_OUTPUT.PUT_LINE(‘Negativo’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘Caso dudoso’);
END CASE;

CASE paisOrigen
WHEN 'Rusia’ THEN
DBMS_OUTPUT.PUT_LINE(‘Gasto muy elevado’);
WHEN 'Alemania’ THEN
DBMS_OUTPUT.PUT_LINE(‘Gasto elevado’);
WHEN ‘Francia’ THEN
DBMS_OUTPUT.PUT_LINE(‘Gasto medio’);
WHEN 'Turquia’ THEN
DBMS_OUTPUT.PUT_LINE(‘Gasto bajo’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘Gasto deconocido’);

END CASE;

Sentencia GOTO

PL/SQL dispone de la sentencia GOTO. La sentencia GOTO desvía el flujo de ejecución


a una determinada etiqueta. Estas sentencias están en desuso porque no son
estrictamente necesarias y dificultan el seguimiento de un programa a la hora de
mantenerlo. No las usaremos en el curso.

En PL/SQL las etiquetas se indican del siguiente modo: << etiqueta >>

El siguiente ejemplo ilustra el uso de GOTO .

DECLARE
flag NUMBER;
BEGIN
flag :=1 ;
IF (flag = 1) THEN
GOTO paso2;
END IF;
<<paso1>>
dbms_output.put_line('Ejecucion de paso 1');
<<paso2>>
dbms_output.put_line('Ejecucion de paso 2');
END;

Bucles

En PL/SQL tenemos a nuestra disposición los siguientes iteradores o bucles:

 LOOP
 WHILE
 FOR

El bucle LOOP, se repite tantas veces como sea necesario hasta que se fuerza su
salida con la instrucción EXIT. Es el bucle más básico. Repite indefinidamente las
instrucciones de su interior hasta que ayudado por un IF activa el EXIT. Su sintaxis es la
siguiente:

LOOP
-- Instrucciones
IF (expresion) THEN
-- Instrucciones
EXIT;
END IF;
END LOOP;

El bucle WHILE, se repite mientras que se cumpla expresion. Una vez que la condición
no se cumple se abandona el bucle, por lo que dentro del mismo ha de haber alguna
instrucción que cambie dicha condición o de lo contrario estaremos en un bucle infinito, lo que
es una de las causas de errores de programación.

WHILE (expresion) LOOP


-- Instrucciones
END LOOP;

El bucle FOR, se repite tantas veces como le indiquemos en los


identificadores inicio y final.

FOR contador IN [REVERSE] inicio..final LOOP

-- Instrucciones
END LOOP;

En el caso de especificar REVERSE el bucle se recorre en sentido inverso.

Ejemplos del uso de estos bucles para conseguir el mismo resultado, imprimir del 1 al
100:

En todos los casos previamente hay que incluir SET SERVEROUTPUT ON


DECLARE
N INT:=0;
BEGIN
LOOP
DBMS_OUTPUT.PUT_LINE(N);
N:=N+1;
IF N>=100 THEN
EXIT;
END IF;
END LOOP;
END;
/

DECLARE
N INT:=0;
BEGIN
WHILE N<=100 LOOP
DBMS_OUTPUT.PUT_LINE(N);
N:=N+1;
END LOOP;
END;
/

BEGIN
FOR i IN 0..100 LOOP
DBMS_OUTPUT.PUT_LINE(i);
END LOOP;
END;
/

También podría gustarte