Está en la página 1de 9

¿Qué es un disparador o trigger en mySql?

Los disparadores o triggers son objetos cuyo


objetivo es ejecutar el código en respuesta a un
evento que ocurre en una tabla. Los eventos
pueden ser de tres tipos: INSERT, UPDATE o
DELETE (o similares, por ejemplo: la instrucción
REPLACE equivalente a INSERT, o INSERT y
DELETE).
¿Qué hace el trigger o disparador ON
DELETE CASCADE?
En MySQL, desde el año 2005, está reportado un
bug bastante preocupante que viola los
principios ACID de una base de datos (concretamente
el de la «Consistencia»).

Este bug consiste básicamente en que los triggers que


se asignen a tablas para que se ejecuten antes o
después de algún evento (por ejemplo, AFTER DELETE
ON <table>), no se ejecutan si dichas tablas son hijas
de otra que provoca dicho evento en cascada (por
ejemplo, un ON DELETE CASCADE). Esto es:

 Si una entidad ‘B’ (siguiendo el modelo entidad-


relación) es débil respecto a otra entidad ‘A’ y…
 Si ‘B’ tiene un trigger del tipo AFTER <evento> ON
‘B’…
 Al producirse el evento <evento> en una tupla de
‘A’ (que provocará una reacción en cascada en la
tupla de ‘B’ relacionada con la tupla de ‘A’) el
trigger de ‘B’ nunca será ejecutado, pero la tupla
de ‘B’ sí que se verá afectada por el evento en
cascada.
Por ejemplo, si ‘B’ tiene un trigger AFTER DELETE ON
‘B’, borrar una tupla de ‘A’ implicará el borrado de una
tupla de ‘B’ pero nunca ejecutará el trigger de ‘B’.

 idLog: valor autoincremental de la tabla histórica.


 dateTimeLog: la fecha/hora en la que se realizó el log.
 operation: qué operación ha provocado su inserción en
esta tabla histórica (‘DELETE’, ‘UPDATE’ ó ‘INSERT’).
ATENCIÓN, no deberíamos tener entidades
aisladas: Siendo puristas, las entidades
nunca deben estar aisladas del resto del
modelo E-R, pero vamos a «romper las
normas» para este ejemplo.
Para conseguir que la tabla_hija sea
entidad débil respecto de la tabla_padre,
creamos una relación ON DELETE CASCADE
en el atributo «tabla_hija.padre_id» (que
apuntará al «id» de la tabla_padre)
ALTER TABLE `tabla_hija`
ADD CONSTRAINT `hija pertenece a padre`
FOREIGN KEY (`padre_id`)
REFERENCES `tabla_padre` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE;

/*TABLA_PADRE*/
/*DELETE*/
CREATE TRIGGER `log_delete_fila_padre`
AFTER DELETE ON `tabla_padre`
FOR EACH ROW
INSERT INTO `tabla_padre_log` (
`idLog`, `dateTimeLog`, `operation`, `id`, `attr1`, `attr2`,
`attr3`)
VALUES
(NULL, NOW(), 'DELETE', OLD.id, OLD.attr1, OLD.attr2,
OLD.attr3);
/*TABLA_HIJA*/
/*DELETE*/
CREATE TRIGGER `log_delete_fila_hija`
AFTER DELETE ON `tabla_hija`
FOR EACH ROW
INSERT INTO `tabla_hija_log` (
`idLog`, `dateTimeLog`, `operation`, `id`, `padre_id`, `attr2`,
`attr3`)
VALUES
(NULL, NOW(), 'DELETE', OLD.id, OLD.padre_id, OLD.attr2,
OLD.attr3)

¿Qué hace el trigger o disparador ON


UPDATE CASCADE?
Uso ON DELETE CASCADE con regularidad, pero
nunca uso ON UPDATE CASCADE porque no
estoy tan seguro de en qué situación será útil.

En aras de la discusión, veamos un poco de


código.
CREATE TABLE parent (
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
);

CREATE TABLE child (


id INT NOT NULL AUTO_INCREMENT, parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id)
REFERENCES parent(id)
ON DELETE CASCADE
);
Para ON DELETE CASCADE, si se elimina un
padre con una identificación, se eliminará
automáticamente un registro en el hijo con
parent_id = parent.id. Esto no debería ser un
problema.

¿Esto significa que ON UPDATE CASCADE hará


lo mismo cuando se actualice la identificación
del padre?

Si (1) es verdadero, significa que no hay


necesidad de usar ON UPDATE CASCADE si
parent.id no se puede actualizar (o nunca se
actualizará) como cuando es AUTO_INCREMENT
o siempre se configura como TIMESTAMP. ¿Está
bien?

Si (2) no es cierto, ¿en qué otro tipo de


situación deberíamos usar ON UPDATE
CASCADE?

¿Qué pasa si (por alguna razón) actualizo


child.parent_id para que sea algo que no existe,
se eliminará automáticamente?
Bueno, lo sé, algunas de las preguntas
anteriores se pueden probar mediante
programación para comprenderlas, pero
también quiero saber si algo de esto depende
del proveedor de la base de datos o no.
COMO CREAR UN TRIGGER
Vamos a crear un trigger que actualice automáticamente el
precio de los productos de la tabla creada en el apartado anterior
cada vez que se actualice su coste. Le
llamaremos actualizarPrecioProducto.

El trigger comprobará si el coste del producto ha cambiado y, en


caso afirmativo, establecerá el precio del producto con el doble
del valor de su coste. Para crear el trigger, ejecuta las siguientes
sentencias SQL:

DELIMITER $$
CREATE TRIGGER 'actualizarPrecioProducto'
BEFORE UPDATE ON 'productos'
FOR EACH ROW
BEGIN
IF NEW.coste <> OLD.coste
THEN
SET NEW.precio = NEW.coste * 2;
END IF ;
END$$
DELIMITER ;
Lo que hacemos es crear un trigger que se ejecute antes de la
actualización del registro, algo que indicamos con la sentencia
«BEFORE UPDATE ON«. Luego comprobamos si el coste antiguo
del producto difiere del nuevo y, si es así, actualizamos el precio
con el doble del valor de su nuevo coste. Un negocio redondo.

ómo utilizar un trigger


Una vez hayamos creado el trigger, no tendremos que hacer
absolutamente nada para llamarlo, puesto que el motor de la base
de datos lo invocará automáticamente cada vez que se actualice
un registro de la tabla de productos.

Sin embargo, sí podemos comprobar el resultado del


trigger actualizando un registro con una sentencia UPDATE como
esta:

UPDATE productos SET coste = 5 WHERE id = 1;


SELECT * FROM productos;
Cuando se ejecuta la actualización con la sentencia UPDATE, se
activa también el trigger, que actualizará el precio con el doble de
su valor, según lo hemos definido. Este será el resultado:
+-----------------+-------+--------+
| id | nombre | coste | precio |
+----+------------+-------+--------+
| 1 | Producto A | 5 | 10 |
| 2 | Producto B | 2 | 4 |
| 3 | Producto C | 40 | 80 |
+----+------------+-------+--------+
Se trata de un ejemplo muy básico del uso de un trigger, pero es
bastante ilustrativo con fines introductorios.
¿Para qué sirve en mysql el tipo de tabla InnoDBy cuál es su
diferencia con respecto a MyISAM?
InnoDB almacena sus tablas e índices en un espacio de tablas que puede estar formado
de varios ficheros o varias particiones. Por el contrario cada tabla MyISAM almacenada
en disco genera tres ficheros con el mismo nombre, que será el nombre de la tabla, pero
diferentes extensiones.

También podría gustarte