Está en la página 1de 6

Prctica 6: Disparadores y PL/SQL

1 Tablas Iniciales 2 Introduccin a los Disparadores 3 Un poco de PL/SQL 4 Sintaxis de instrucciones PL/SQL 5 Preguntas

1 Tablas Iniciales
En esta prctica vamos a utilizar las siguientes tablas, que representan las ventas de una frutera
-- adaptamos el formato de fecha ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MM-YYYY HH24:MI'; -- para que se muestren mensajes por la consola set serveroutput on; create table fruteria ( nombre varchar(10) primary key, kilos float disponibles ); -- nombre de la fruta -- kilos

create table preciofruta ( nombre varchar(10) primary key references fruteria, preciokilo float ); create table ventafruta ( nombre varchar(10) references fruteria, cantidad float, -- cantidad vendida importe float, -- total a pagar fecha date, -- fecha de la venta primary key (nombre,fecha)

); create table pedido ( id integer primary key, nombre references fruteria, cantidad float -- kilos pedidos ); create table llegapedido( id integer primary key );

En la frutera se vende fruta por kilos. Cuando se ve que se va a agotar una fruta se hace un pedido.

2 Introduccin a los disparadores


Los disparadores o triggers permiten ejecutar acciones asociadas a inserciones, borrado y modificaciones de bases de datos. La sintaxis general es:

CREATE [OR REPLACE] TRIGGER nombre {BEFORE|AFTER} {INSERT|DELETE|UPDATE} ON [REFERENCING [NEW AS ] [OLD AS ]] [FOR EACH ROW [WHEN ()]] [DECLARE] dec. variables BEGIN instrucciones [EXCEPTIONS] trat. excepciones END nombre; /

Como se observa podemos indicar que el disparador puede lanzarse antes o despus de la accin. La instruccin for each row significa que se van a a tratar una a una las filas modificadas, es decir es como si el disparador se ejecutase una vez por cada fila modificada. Las instrucciones incluyen sentencias SQL y otras de control como If...then. Veamos un ejemplo:
CREATE OR REPLACE TRIGGER insertafruteria BEFORE INSERT ON fruteria FOR EACH ROW BEGIN DBMS_OUTPUT.PUT_LINE('Insercin en fruteria de ' || :new.nombre ||

' Cantidad: ' || :new.kilos); END;

El disparador muestra un mensaje por pantalla cada vez que se inserta en fruteria. Para comprobarlo introducir los valores:
insert insert insert insert into into into into fruteria fruteria fruteria fruteria values('Manzanas',23); values('Naranjas',150); values('Kiwis',50); values('Fresas',80);

Los errores de compilacin pueden verse con show errors trigger nombre; El trigger puede ser borrado en cualquier momento con drop trigger nombre;, tambin puede ser deshabilitado momentneamente o habilitado de nuevo con alter trigger nombre {disable|enable};. Una de las utilidades de los trigger es comprobar que no se introducen valores errneos, por ejemplo valores negativos. Por ejemplo podemos crear:
CREATE OR REPLACE TRIGGER insertapreciofruta BEFORE INSERT ON preciofruta FOR EACH ROW BEGIN IF (:new.preciokilo<0) THEN RAISE_APPLICATION_ERROR(-20000, 'No se admiten valores negativos'); END IF; END;

El valor :new se refiere a la nueva tupla a insertar. Tambin se puede utilizar :old para la tupla que se est reemplazando en el caso de update o delete. Y ahora intentamos las inserciones:
insert insert insert insert into into into into preciofruta preciofruta preciofruta preciofruta values('Manzanas',1.5); values('Naranjas',1.1); values('Kiwis',-6); values('Fresas',3.2);

Pregunta 1 Pregunta 2

3 Un poco de PL/SQL
La estructura del cuerpo del trigger es la de un bloque PL/SQL:

DECLARE /* Declaracin de variables, tipos y subprogramas */ BEGIN Instrucciones

EXCEPTION /* Tratamiento de excepciones */ END;

Las variables se declaran mediante su tipo, como por ejemplo:


i integer;

Tambin se pueden declarar para que su tipo sea el de una columna de una tabla, como por ejemplo:
fruta fruteria.nombre%TYPE;

Fruta es del mismo tipo que la columna nombre de fruteria, es decir varchar(10). Se pueden asignar valores a las variables directamente con :=, o mediante una sentencia select into, como muestra el ejemplo de disparador siguiente:
CREATE OR REPLACE TRIGGER insertapreciofruta BEFORE INSERT ON preciofruta FOR EACH ROW DECLARE haykilos fruteria.kilos%TYPE; BEGIN select kilos into haykilos from fruteria where nombre = :new.nombre; DBMS_OUTPUT.PUT_LINE('Producto ' || :new.nombre || ' Nuevo precio: ' || :new.preciokilo || ' Cantidad disponible: ' || haykilos); END;

Este disparador mostrar la cantidad de kilos disponibles al insertar el precio. Hay que tener cuidado al escribir la instruccin select: Si la consulta devuelve 0 valores o ms de uno se obtendr un error y se saltar a la parte de control de excepciones. Para probar el disparador escribimos:
delete insert insert insert insert from into into into into preciofruta; preciofruta values('Manzanas',1.5); preciofruta values('Naranjas',1.1); preciofruta values('Kiwis',6); preciofruta values('Fresas',3.2);

Pregunta 3

4 Sintaxis de instrucciones PL/SQL

La sintaxis de la instruccin IF en PL/SQL es:

IF <condition_1> THEN ... ELSIF <condition_2> THEN ... ... ... ELSIF <condition_n> THEN ... ELSE ... END IF;

Los bucles disponibles en PL/SQL son loop, while y for. El caso de LOOP:
LOOP /* instrucciones */ END LOOP;

Al menos una instruccin debe ser exit para salir del bucle EXIT WHEN <condition>; Por ejemplo:
DECLARE i NUMBER := 1; BEGIN LOOP< INSERT INTO T1 VALUES(i,i); i := i+1; EXIT WHEN i>100; END LOOP; END;

De esta forma se insertan 100 valores en la tabla T1. La sintaxis de WHILE


WHILE <condition> LOOP instrucciones END LOOP;

y for:
FOR var IN .. LOOP instrucciones END LOOP;

Un aspecto muy importante que no tratamos en esta prctica son los cursores y los procedimientos. Para aprender ms se puede ver una introduccin sencilla a PL/SQL en:

http://infolab.stanford.edu/~ullman/fcdb/oracle/orplsql.html#basic%20structure%20of%20pl/sql

5 Preguntas
Pregunta 4 Pregunta 5

También podría gustarte