MySQL 馃惉 : Trabajar con Trigger
Los triggers (disparadores) en MySQL son una poderosa herramienta que nos permite ejecutar autom谩ticamente ciertas acciones en respuesta a eventos espec铆ficos en la base de datos. En otras palabras, un trigger se asocia a una tabla y se ejecuta autom谩ticamente cuando ocurre un evento de modificaci贸n de datos (INSERT
, UPDATE
, DELETE
) en esa tabla.
Vamos a ver varios ejemplos pr谩cticos de como usar triggers en MySQL 5.7 y versiones superiores.
Sintaxis B谩sica para crear un Trigger
La sintaxis b谩sica para crear un trigger en MySQL es la siguiente:
1
2
3
4
5
6
7
8
9
10
11
DELIMITER ::
CREATE TRIGGER nombre_trigger
[BEFORE | AFTER] [INSERT | UPDATE | DELETE]
ON nombre_tabla
FOR EACH ROW
BEGIN
-- Sentencias SQL a Ejecutar
END::
DELIMITER ;
Explicaci贸n de sintaxis:
DELIMITER
: cambia el car谩cter que MySQL usa para identificar el final de una instrucci贸n SQL.nombre_trigger
: El nombre que le damos al trigger.BEFORE | AFTER
: Especifica si el trigger se ejecutar谩 antes o despu茅s del evento.INSERT | UPDATE | DELETE
: El tipo de evento que activar谩 el trigger.nombre_tabla
: La tabla sobre la que se activa el trigger.FOR EACH ROW
: Significa que el trigger se ejecuta una vez por cada fila afectada por la consulta.- Bloque
BEGIN ... END;
: Contiene las sentencias SQL que se ejecutar谩n cuando el trigger sea activado.
En MySQL, cuando se define un trigger, especialmente cuando se incluye una estructura como BEGIN ... END
, necesitas asegurarte de utilizar el delimitador adecuado para que el c贸digo del trigger se ejecute correctamente.
Por defecto, MySQL usa ;
como delimitador, pero esto puede causar problemas si el trigger incluye m煤ltiples instrucciones SQL dentro de BEGIN ... END
. Debes cambiar temporalmente el delimitador para evitar que MySQL interprete el ;
interno del trigger.
Trigger para Auditar Cambios en una Tabla
Supongamos que tenemos una tabla llamada productos
y queremos llevar un registro de todos los cambios realizados (insertar, actualizar o eliminar) en una tabla de auditor铆a productos_auditoria
.
Paso 1: Crear la Base de Datos y Seleccionarla
Para ello vamos a crear una base de datos llamada bd_tienda
para trabajar y la seleccionamos:
1
2
CREATE DATABASE `bd_tienda`;
USE bd_tienda;
Paso 2: Crear las Tablas
Una vez seleccionada la base de datos, creamos la tabla productos
y la tabla productos_auditoria
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TABLE productos (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(100),
precio INT,
stock INT
);
CREATE TABLE productos_auditoria (
id INT AUTO_INCREMENT PRIMARY KEY,
producto_id INT,
accion VARCHAR(10),
fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
datos_anterior JSON
);
Paso 3: Crear un Trigger para Insertar en la Auditor铆a
Queremos que cada vez que se inserte un nuevo producto, se registre en productos_auditoria
. El trigger se ejecutar谩 despu茅s de la inserci贸n de un nuevo producto:
1
2
3
4
5
6
7
8
9
10
11
DELIMITER ::
CREATE TRIGGER after_insert_producto
AFTER INSERT ON productos
FOR EACH ROW
BEGIN
INSERT INTO productos_auditoria (producto_id, accion, datos_anterior)
VALUES (NEW.id, 'INSERT', JSON_OBJECT('nombre', NEW.nombre, 'precio', NEW.precio,'stock', NEW.stock));
END::
DELIMITER ;
Aqu铆 tenemos algunas palabras claves que no se explican en la sintaxis b谩sica pero se utilizan para lo siguiente:
NEW
: En un trigger,NEW
hace referencia a los valores que se est脿n insertando o modificando. En este caso, estamos utilizando los valores reci茅n insertados en la tablaproductos
.JSON_OBJECT
: Esta funci贸n crea un objeto JSON con los datos del producto insertado.
Paso 4: Probar el Trigger
Insertamos un producto y verificamos que se registre en la tabla auditor铆a:
1
2
3
4
INSERT INTO productos (nombre, precio, stock)
VALUES ('Camiseta', 14990, 100);
SELECT * FROM productos_auditoria;
Esto deber铆a registrar una fila en la tabla productos_auditoria
con la acci贸n 'INSERT'
y los datos del nuevo producto.
mysql> INSERT INTO productos (nombre, precio, stock) VALUES ('Camiseta', 14990, 100);
Query OK, 1 row affected (0.03 sec)
mysql> SELECT * FROM productos_auditoria;
+----+-------------+--------+---------------------+-------------------------------------------------------+
| id | producto_id | accion | fecha | datos_anterior |
+----+-------------+--------+---------------------+-------------------------------------------------------+
| 1 | 1 | INSERT | 2024-10-25 18:08:35 | {"stock": 100, "nombre": "Camiseta", "precio": 14990} |
+----+-------------+--------+---------------------+-------------------------------------------------------+
1 row in set (0.00 sec)
Trigger Para evitar la Eliminaci贸n de Productos con Stock
Ahora, supongamos que queremos evitar que los usuarios eliminen productos si su stock
es mayor que cero. Utilizaremos un trigger antes de la eliminaci贸n (BEFORE DELETE
).
Paso 1: Crear el Trigger
1
2
3
4
5
6
7
8
9
10
11
12
DELIMITER ::
CREATE TRIGGER before_delete_producto
BEFORE DELETE ON productos
FOR EACH ROW
BEGIN
IF OLD.stock > 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'No se puede eliminar el producto con stock disponible';
END IF;
END::
DELIMITER ;
Aqu铆 tenemos algunas palabras claves que no se explican en la sintaxis b谩sica pero se utilizan para lo siguiente:
OLD
: Hace referencia a los valores de la fila antes de la operaci贸n (DELETE
), en este caso, el valor destock
antes de eliminar el producto.SIGNAL SQLSTATE
: Genera una se帽al de error personalizado, interrumpiendo la operaci贸n.SQLSTATE '45000'
: C贸digo de error definido por el usuario para lanzar una excepci贸n personalizada.SET MESSAGE_TEXT = '...'
: Define el mensaje de error que se muestra cuando se activa la se帽al.
Paso 2: Probar el Trigger
Eliminamos un producto existente que tenga stock > 0
y verificamos que se dispare el trigger:
1
DELETE FROM productos WHERE nombre = 'Camiseta';
Esto deber铆a desencadenar el evento y disparar el trigger before_delete_producto
mostrando el mensaje de la excepci贸n:
mysql> DELETE FROM productos WHERE nombre = 'Camiseta';
ERROR 1644 (45000): No se puede eliminar el producto con stock disponible
Consideraciones sobre los Trigger
Como hemos visto los triggers en MySQL son una herramienta poderosa para automatizar, auditar, etc. Pero debemos considerar los siguiente:
- impacto en el rendimiento: Los triggers pueden afectar el rendimiento, especialmente cuando se ejecutan operaciones complejas o se disparan con mucha frecuencia.
- recursividad: Ten cuidado con los trigger recursivos. Si un trigger realiza una operaci贸n que activa el mismo trigger nuevamente, puede llevar a una recursi贸n infinita.
Mi lema es