Upload
rsmaster69
View
99
Download
7
Embed Size (px)
Citation preview
• Clase especial de procedimiento almacenado que se ejecuta automáticamente (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 ejecución.• Los triggers se definen para una tabla específica,
denominada tabla del trigger.
• Mysql no soporta multiples triggers para una misma accion en una misma tabla…aun.
• 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 después (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 después de la modificación.
• Los INSERT permiten NEW, los DELETE sólo OLD y los UPDATE ambas.
• No es posible invocar directamente los triggers, que tampoco pasan ni aceptan parámetros.
• Gran herramienta para controlar reglas de negocio más complejas que una simple integridad referencial.
• Ojo: el usuario no espera que el trigger le devuelva registros luego de agregar o modificar información. (no lo hace).
• Las personas que se registren en la BD universidad deben ser mayores de 18 años.
• Cómo 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 personaFOR EACH ROWBEGINdeclare 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 personaFOR EACH ROWBEGINdeclare 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 productoFOR EACH ROWBEGINIF 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 productoFOR EACH ROWBEGINIF 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 productoFOR EACH ROWBEGINIF (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 productoFOR EACH ROWBEGINIF 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_ventaFOR EACH ROWBEGINupdate productoset stock=stock-new.cantidadwhere 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…
• 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
productoFOR EACH ROWBEGIN
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.
• Cómo sería 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
sucursalFOR EACH ROWBEGINinsert 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 sucursalFOR EACH ROWBEGINif 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 productoFOR EACH ROWBEGINif 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 productoFOR EACH ROWBEGINinsert 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;$