En MySQL, los eventos y disparadores (triggers) permiten ejecutar automáticamente código SQL en respuesta a eventos programados o cambios en la base de datos.
✅ Eventos (EVENTS
) → Se ejecutan en un momento programado (tareas automáticas).
✅ Disparadores (TRIGGERS
) → Se activan cuando ocurre una acción en una tabla (INSERT
, UPDATE
, DELETE
).
EVENTS
)Los eventos programados en MySQL permiten ejecutar tareas automáticamente a una hora específica o en intervalos de tiempo.
Antes de crear eventos, asegúrate de que el scheduler esté activado:
SET GLOBAL event_scheduler = ON;
🔹 Verificar si está activo
SHOW VARIABLES LIKE 'event_scheduler';
CREATE EVENT EliminarRegistrosAntiguos
ON SCHEDULE EVERY 1 DAY
DO
BEGIN
DELETE FROM logs WHERE fecha < NOW() - INTERVAL 30 DAY;
END;
🔹 Explicación:
logs
que tengan más de 30 días.CREATE EVENT ActualizarPrecios
ON SCHEDULE AT '2025-04-01 00:00:00'
DO
BEGIN
UPDATE productos SET precio = precio * 1.05;
END;
🔹 Explicación:
🔹 Ver todos los eventos programados
SHOW EVENTS;
🔹 Eliminar un evento
DROP EVENT IF EXISTS EliminarRegistrosAntiguos;
TRIGGERS
)Los triggers ejecutan código automáticamente cuando ocurre un cambio (INSERT
, UPDATE
, DELETE
) en una tabla.
Técnicamente, un trigger es un objeto de una base de datos que está asociado a una tabla, y que será activado cuando la acción que tiene asociada tiene lugar. El trigger se puede ejecutar cuando tiene lugar una acción INSERT, UPDATE o DELETE, siendo posible su ejecución tanto antes como después del evento (BEFORE / AFTER).
CREATE
[DEFINER = { user | CURRENT_USER }]
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
[trigger_order]
trigger_body
trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE }
trigger_order: { FOLLOWS | PRECEDES } other_trigger_name
Un trigger es un objeto de la base de datos que está asociado con una tabla y que se activa cuando ocurre un evento sobre la tabla.
Los eventos que pueden ocurrir sobre la tabla son:
La siguiente tabla ilustra la disponibilidad de los modificadores OLD y NEW:
Tipo de Trigger | Se Activa Antes/Después de… |
---|---|
BEFORE INSERT | Antes de insertar un registro |
AFTER INSERT | Después de insertar un registro |
BEFORE UPDATE | Antes de actualizar un registro |
AFTER UPDATE | Después de actualizar un registro |
BEFORE DELETE | Antes de borrar un registro |
AFTER DELETE | Después de borrar un registro |
AFTER INSERT
)CREATE TABLE auditoria (
id INT AUTO_INCREMENT PRIMARY KEY,
accion VARCHAR(50),
fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
DELIMITER $$
CREATE TRIGGER RegistrarInsercion
AFTER INSERT ON clientes
FOR EACH ROW
BEGIN
INSERT INTO auditoria (accion) VALUES ('INSERT en clientes');
END $$
DELIMITER ;
🔹 Explicación:
clientes
.auditoria
.BEFORE INSERT
)DELIMITER $$
CREATE TRIGGER ValidarEmail
BEFORE INSERT ON usuarios
FOR EACH ROW
BEGIN
IF EXISTS (SELECT 1 FROM usuarios WHERE email = NEW.email) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Email ya existe';
END IF;
END $$
DELIMITER ;
🔹 Explicación:
BEFORE DELETE
)DELIMITER $$
CREATE TRIGGER EvitarBorradoCliente
BEFORE DELETE ON clientes
FOR EACH ROW
BEGIN
IF (SELECT COUNT(*) FROM pedidos WHERE id_cliente = OLD.id_cliente) > 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'No se puede borrar el cliente con pedidos activos';
END IF;
END $$
DELIMITER ;
🔹 Explicación:
pedidos
, evita su eliminación.🔹 Ver triggers en la base de datos
SHOW TRIGGERS;
🔹 Eliminar un trigger
DROP TRIGGER IF EXISTS RegistrarInsercion;
Característica | Eventos (EVENTS ) |
Disparadores (TRIGGERS ) |
---|---|---|
Cuándo se ejecuta | En un momento programado | Cuando ocurre un INSERT , UPDATE , DELETE |
Frecuencia | Periódico o una sola vez | Se ejecuta en cada operación sobre la tabla |
Se aplica a múltiples registros? | ✅ Sí, puede afectar toda la tabla | ❌ No, se ejecuta por cada fila modificada |
Se puede programar a futuro? | ✅ Sí | ❌ No |
Ejemplo de uso | Limpieza de registros antiguos | Auditoría de cambios en la base de datos |
Crea una base de datos llamada test que contenga una tabla llamada alumnos con las siguientes columnas.
Tabla alumnos:
id (entero sin signo)
nombre (cadena de caracteres)
apellido1 (cadena de caracteres)
apellido2 (cadena de caracteres)
nota (número real)
Una vez creada la tabla escriba dos triggers con las siguientes características:
Trigger 1: trigger_check_nota_before_insert
- Se ejecuta sobre la tabla alumnos.
- Se ejecuta antes de una operación de inserción.
- Si el nuevo valor de la nota que se quiere insertar es negativo, se guarda como 0.
- Si el nuevo valor de la nota que se quiere insertar es mayor que 10, se guarda como 10.
Trigger2 : trigger_check_nota_before_update
- Se ejecuta sobre la tabla alumnos.
- Se ejecuta antes de una operación de actualización.
- Si el nuevo valor de la nota que se quiere actualizar es negativo, se guarda como 0.
- Si el nuevo valor de la nota que se quiere actualizar es mayor que 10, se guarda como 10.
Una vez creados los triggers escriba varias sentencias de inserción y actualización sobre la tabla alumnos y verifica que los triggers se están ejecutando correctamente.
-- Paso 1
DROP DATABASE IF EXISTS test;
CREATE DATABASE test;
USE test;
-- Paso 2
CREATE TABLE alumnos (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(50) NOT NULL,
apellido1 VARCHAR(50) NOT NULL,
apellido2 VARCHAR(50),
nota FLOAT
);
-- Paso 3
DELIMITER $$
DROP TRIGGER IF EXISTS trigger_check_nota_before_insert$$
CREATE TRIGGER trigger_check_nota_before_insert
BEFORE INSERT
ON alumnos FOR EACH ROW
BEGIN
IF NEW.nota < 0 THEN
set NEW.nota = 0;
ELSEIF NEW.nota > 10 THEN
set NEW.nota = 10;
END IF;
END
DELIMITER $$
DROP TRIGGER IF EXISTS trigger_check_nota_before_update$$
CREATE TRIGGER trigger_check_nota_before_update
BEFORE UPDATE
ON alumnos FOR EACH ROW
BEGIN
IF NEW.nota < 0 THEN
set NEW.nota = 0;
ELSEIF NEW.nota > 10 THEN
set NEW.nota = 10;
END IF;
END
-- Paso 4
DELIMITER ;
INSERT INTO alumnos VALUES (1, 'Pepe', 'López', 'López', -1);
INSERT INTO alumnos VALUES (2, 'María', 'Sánchez', 'Sánchez', 11);
INSERT INTO alumnos VALUES (3, 'Juan', 'Pérez', 'Pérez', 8.5);
-- Paso 5
SELECT * FROM alumnos;
-- Paso 6
UPDATE alumnos SET nota = -4 WHERE id = 3;
UPDATE alumnos SET nota = 14 WHERE id = 3;
UPDATE alumnos SET nota = 9.5 WHERE id = 3;
-- Paso 7
SELECT * FROM alumnos;
SET GLOBAL event_scheduler = ON;
CREATE DEFINER=`root`@`localhost` EVENT `alarma`
ON SCHEDULE
EVERY 10 SECOND STARTS '2022-05-09 20:15:24'
ON COMPLETION PRESERVE
ENABLE
COMMENT ''
DO BEGIN
INSERT INTO log VALUES
(NULL,SYSDATE(),"tictac",
NULL, USER(), NULL, null);
END
Ejemplo eMail:
CREATE TABLE `email` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`fecha` DATETIME NULL DEFAULT NULL,
`de` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
`para` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
`asunto` VARCHAR(200) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
`cuerpo` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
`papelera` TINYINT(4) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
);
CREATE TRIGGER `email_before_delete` BEFORE DELETE ON `email` FOR EACH ROW BEGIN
INSERT INTO log VALUES
(NULL,SYSDATE(),"limpia.email",
CONCAT("email ->","id:",OLD.id),
USER(), OLD.de, OLD.para);
END
Eventos:
ALTER DEFINER=`root`@`localhost` EVENT `limpia_email`
ON SCHEDULE EVERY 10 SECOND STARTS '2022-05-09 20:48:11'
DO BEGIN
DELETE FROM email
WHERE
papelera = 1 and
DATEDIFF(SYSDATE(),fecha) > 30;
END
Evento mejorado:
CREATE DEFINER=`root`@`localhost` EVENT `limpia_email`
ON SCHEDULE
EVERY 10 SECOND STARTS '2022-05-09 20:48:11'
ON COMPLETION PRESERVE
ENABLE
COMMENT ''
DO BEGIN
DECLARE i INT;
SELECT COUNT(id) INTO i FROM email
WHERE papelera = 1 and
DATEDIFF(SYSDATE(),fecha) > 30;
if (i > 0) then
INSERT INTO log VALUES (
DEFAULT, SYSDATE(),
"email-> Correo papelera",
CONCAT("Borrar ",i," correos"),
USER(),NULL, NULL);
DELETE FROM email
WHERE papelera = 1 and
DATEDIFF(SYSDATE(),fecha) > 30;
END if;
END
✅ Usa eventos (EVENTS
) para tareas programadas, como limpieza de datos o actualizaciones automáticas.
✅ Usa triggers (TRIGGERS
) para auditoría y validaciones antes de que se ejecuten cambios en la base de datos.
✅ Evita triggers demasiado complejos, pueden afectar el rendimiento.
✅ Verifica los permisos de los eventos y triggers (GRANT EVENT
, GRANT TRIGGER
).
✅ Siempre prueba los eventos y triggers en un entorno de prueba antes de implementarlos en producción.