Sunteți pe pagina 1din 37

Triggers-Disparadores

Clase especial de procedimiento almacenado que se ejecuta automticamente (se dispara) cuando se produce un evento especifico. Se ejecuta siempre que se intenta modificar los datos de una tabla que el trigger protege: realizar un INSERT, UPDATE o DELETE. No es posible evitar su ejecucin. Los triggers se definen para una tabla especfica, denominada tabla del trigger. Mysql no soporta multiples triggers para una misma accion en una misma tablaaun.

Los eventos pueden ser las sentencias INSERT, DELETE, UPDATE que modifican los datos de una tabla. Los triggers se pueden ejecutar antes (BEFORE) y/o despus (AFTER) de que sean modificados los datos.
Los triggers tienen dos palabras clave, OLD y NEW que se refieren a los valores que tienen las columnas antes y despus de la modificacin. Los INSERT permiten NEW, los DELETE slo OLD y los UPDATE ambas.

Sintaxis:

No es posible invocar directamente los triggers, que tampoco pasan ni aceptan parmetros. Gran herramienta para controlar reglas de negocio ms complejas que una simple integridad referencial. Ojo: el usuario no espera que el trigger le devuelva registros luego de agregar o modificar informacin. (no lo hace).

INSERT
Aplicar reglas de negocio??? Validacion de datos.

Las personas que se registren en la BD universidad deben ser mayores de 18 aos. Cmo seria la condicion? Before insert o after insert??

Condicion a para validar: IF ((datediff(curdate(),fecha_nacimiento))/365)<18 THEN

Qu se debe hacer o no hacer al cumplirse esta condicion???

DELIMITER $ CREATE TRIGGER insert_persona BEFORE INSERT ON persona FOR EACH ROW BEGIN declare fecha date; set fecha=new.fecha_nacimiento; IF ((datediff(curdate(),fecha))/365)<18 THEN END IF; END; $

DELIMITER $ CREATE TRIGGER insert_persona BEFORE INSERT ON persona FOR EACH ROW BEGIN declare fecha date; set fecha=new.fecha_nacimiento; IF ((datediff(curdate(),fecha))/365)<18 THEN set @msg = 'Trigger Error: menor de edad: '; signal sqlstate '45000' set message_text = @msg; END IF; END; $

Se puede entonces:

Generar un PA simple para insercion, que tome en cuenta reglas de integridad. Generar un trigger on insert que tome en cuenta la regla de negocio.
Ojo: para conocer los triggers generados:
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS show triggers

Ejercicio.
Usar BD practico 1 select. Se necesita insertar un producto cuya fecha de vencimiento sea minimo en 15 dias despues del registro. Si no es asi, no se debe realizar la insercion.

Generar PA de insercion en producto que tome en cuenta integridad referencial (pk y fk). Regla de negocio la manejara trigger: before o after? Hacer pruebas.

DELIMITER $ CREATE TRIGGER insert_producto BEFORE INSERT ON producto FOR EACH ROW BEGIN IF new.fecha_vencimiento-curdate()<15 then set @msg = 'Trigger Error: No se aceptan productos a vencer en menos de 15 dias'; signal sqlstate '45000' set message_text = @msg; END IF; END; $

Ejercicio.

Se necesita insertar un producto nuevo. Si su stock es menor que 10, no se debe realizar la insercion. PA de insercion ya esta creado.*** Generar trigger. Hacer pruebas.

DELIMITER $ CREATE TRIGGER insert_pro_stock BEFORE INSERT ON producto FOR EACH ROW BEGIN IF new.stock<10 then set @msg = 'Trigger Error: No se acepta stock tan bajo'; signal sqlstate '45000' set message_text = @msg; END IF; END; $

Ejercicio.

El almacen solo maneja 5 productos por proveedor registrado en la BD. No se debe poder insertar un nuevo producto si no se cumple esta regla. PA de insercion creado.*** Generar trigger. Hacer pruebas.

DELIMITER $ CREATE TRIGGER insert_pro_prov BEFORE INSERT ON producto FOR EACH ROW BEGIN IF (select count(*) from producto where proveedor_codigo_proveedor=new.proveedor_codigo_proveedor)> =5 then set @msg = 'Trigger Error: No se aceptan mas productos por proveedor'; signal sqlstate '45000' set message_text = @msg; END IF; END; $

Ejercicio.

Insercion en producto. Regla: Si el producto es de marca nestle, no se acepta un stock mayor a 15. PA de insercion creado.*** Generar trigger. Hacer pruebas.

DELIMITER $ CREATE TRIGGER insert_nestle BEFORE INSERT ON producto FOR EACH ROW BEGIN IF new.marca='nestle' and new.stock>15 then set @msg = 'Trigger Error: No se acepta stock mayor a 15 en productos de esta marca'; signal sqlstate '45000' set message_text = @msg; END IF; END; $

Trigger After Insert Para que nos podria servir este tipo de trigger?
Respaldo, auditoria de datos, y..

Se necesita un trigger que, hecha la compra de una cantidad de producto, actualice el stock. Se asume que existe el stock necesario. Que tipo de trigger es? Sobre que tabla? Hacer pruebas.

DELIMITER $ CREATE TRIGGER insert_after_detalle after INSERT ON detalle_venta FOR EACH ROW BEGIN update producto set stock=stock-new.cantidad where codigo_producto=new.producto_codigo_producto; END; $

Ahora, que pasa si no esta el stock necesario? No se podria insertar la compra de tal cantidad de producto

Como seria el trigger? (Complementar anterior) Before o after insert? Pienselo en casa con tranquilidad

Trigger para Update.


Cuando usarlos? Verificar una condicion antes de hacer el update.

Se necesita verificar que, si al modificar el precio de algun producto especifico, este nuevo precio no sea superior al doble del precio actual. Como seria el trigger? Before/after?

DELIMITER $ CREATE TRIGGER insert_before_prod before UPDATE ON producto FOR EACH ROW BEGIN IF new.precio>old.precio*2 then set @msg = 'Trigger Error: No se puede subir tanto los precios'; signal sqlstate '45000' set message_text = @msg; END IF; END; $

Al modificar algun dato de sucursal, se debe manejar un respaldo de estos datos (los antiguos), incluida fecha y usuario que genero la modificacion. Modificar telefono de sucursal. Generar PA para modificacion de sucursal (telefono) a partir de su codigo. Cmo sera el trigger?

create table info2 (id int auto_increment, codigos varchar(8), telefono varchar(20), fecha date, usuario varchar(15), primary key (id));

DELIMITER $ CREATE TRIGGER insert_after_suc after UPDATE ON sucursal FOR EACH ROW BEGIN insert into info2 (codigos, telefono, fecha, usuario) values(old.codigo_sucursal, old.telefono_sucursal, curdate(), current_user()); END; $

Ejercicio. No esta permitido realizar modificaciones los fines de semana. Tomar en cuenta la modificacion de telefono de sucursal. Generar trigger que verifique esto. Before/after?

DELIMITER $ CREATE TRIGGER update_before_suc before UPDATE ON sucursal FOR EACH ROW BEGIN if dayname(curdate()) in ('Saturday','Sunday') then set @msg = 'Trigger Error: No se puede actualizar los fines de semana'; signal sqlstate '45000' set message_text = @msg; END IF; END; $

Trigger para DELETE.


Para qu podria usarse un trigger para delete? Verificar condiciones de borrado. Respaldos.

Ejercicio. El almacen ha decidido que no se pueden eliminar productos de la BD que no hayan vencido aun. Qu tipo de trigger es? BEFORE/AFTER?

DELIMITER $ CREATE TRIGGER delete_prod before delete ON producto FOR EACH ROW BEGIN if old.fecha_vencimiento>curdate() then set @msg = 'Trigger Error: No se puede eliminar productos que aun no esten vencidos'; signal sqlstate '45000' set message_text = @msg; END IF; END; $

Ejercicio. Al eliminarse un producto, se debe manejar un respaldo de los datos eliminados, incluida fecha y usuario que genero la eliminacion. Creacion de tabla respaldo. BEFORE/AFTER?

create table info3 (id int auto_increment, codigos varchar(8), nombre varchar(20), Marca varchar(15), Precio int, Fecha_v date, Stock int, Proveedor varchar(6), Fecha_eliminacion date, usuario varchar(15), primary key (id));

DELIMITER $ CREATE TRIGGER delete_after_prod after delete ON producto FOR EACH ROW BEGIN insert into info3 (codigos, nombre, marca, precio, fecha_v, stock, proveedor, fecha_eliminacion, usuario) values(old.codigo_producto, old.nombre_fantasia, old.marca, old.precio, old.fecha_vencimiento, old.stock, old.proveedor_codigo_proveedor, curdate(), current_user()); END; $

S-ar putea să vă placă și