BEFORE INSERT

Un trigger BEFORE INSERT se ejecuta antes de que una nueva fila se inserte en la tabla. Puede modificar los valores de NEW antes de que se guarden o cancelar la inserción lanzando un error con SIGNAL.

Sintaxis

DELIMITER //
 
CREATE TRIGGER nombre_trigger
BEFORE INSERT ON nombre_tabla
FOR EACH ROW
BEGIN
    -- Acceder y modificar NEW.columna
END //
 
DELIMITER ;

Modificar valores antes de insertar

DELIMITER //
 
CREATE TRIGGER tr_productos_before_insert
BEFORE INSERT ON productos
FOR EACH ROW
BEGIN
    -- Asegurar que el nombre no tenga espacios extra
    SET NEW.nombre = TRIM(NEW.nombre);
 
    -- Si no se especifica stock, poner 0
    IF NEW.stock IS NULL THEN
        SET NEW.stock = 0;
    END IF;
 
    -- Redondear precio a 2 decimales
    SET NEW.precio = ROUND(NEW.precio, 2);
END //
 
DELIMITER ;
INSERT INTO productos (nombre, precio, stock, categoria_id, activo)
VALUES ('  Producto Test  ', 99.999, NULL, 6, TRUE);
 
SELECT nombre, precio, stock FROM productos WHERE nombre = 'Producto Test';
nombrepreciostock
Producto Test100.000

El trigger limpió los espacios, redondeó el precio y asignó stock = 0.

Validar datos

DELIMITER //
 
CREATE TRIGGER tr_pedidos_before_insert
BEFORE INSERT ON pedidos
FOR EACH ROW
BEGIN
    -- Validar que el total no sea negativo
    IF NEW.total < 0 THEN
        SIGNAL SQLSTATE '45000'
        SET MESSAGE_TEXT = 'El total del pedido no puede ser negativo';
    END IF;
 
    -- Validar estado
    IF NEW.estado NOT IN ('pendiente', 'enviado', 'entregado', 'cancelado') THEN
        SIGNAL SQLSTATE '45000'
        SET MESSAGE_TEXT = 'Estado de pedido no válido';
    END IF;
 
    -- Si no se especifica fecha, usar hoy
    IF NEW.fecha IS NULL THEN
        SET NEW.fecha = CURDATE();
    END IF;
END //
 
DELIMITER ;

Valores por defecto calculados

CREATE TABLE codigos_descuento (
    id INT AUTO_INCREMENT PRIMARY KEY,
    codigo VARCHAR(20) UNIQUE,
    porcentaje DECIMAL(5,2),
    fecha_creacion DATETIME,
    fecha_expiracion DATETIME,
    usos_maximos INT DEFAULT 100,
    usos_actuales INT DEFAULT 0
);
DELIMITER //
 
CREATE TRIGGER tr_codigos_before_insert
BEFORE INSERT ON codigos_descuento
FOR EACH ROW
BEGIN
    -- Generar código si no se proporcionó
    IF NEW.codigo IS NULL OR NEW.codigo = '' THEN
        SET NEW.codigo = CONCAT('DESC', UPPER(LEFT(MD5(RAND()), 8)));
    END IF;
 
    -- Establecer fechas
    SET NEW.fecha_creacion = NOW();
 
    IF NEW.fecha_expiracion IS NULL THEN
        SET NEW.fecha_expiracion = DATE_ADD(NOW(), INTERVAL 30 DAY);
    END IF;
 
    -- Validar porcentaje
    IF NEW.porcentaje <= 0 OR NEW.porcentaje > 100 THEN
        SIGNAL SQLSTATE '45000'
        SET MESSAGE_TEXT = 'El porcentaje debe estar entre 0 y 100';
    END IF;
END //
 
DELIMITER ;
INSERT INTO codigos_descuento (porcentaje) VALUES (15);
 
SELECT codigo, porcentaje, fecha_creacion, fecha_expiracion
FROM codigos_descuento;

El trigger generó automáticamente el código, la fecha de creación y la fecha de expiración.

Limpieza

DROP TRIGGER IF EXISTS tr_productos_before_insert;
DROP TRIGGER IF EXISTS tr_pedidos_before_insert;
DROP TRIGGER IF EXISTS tr_codigos_before_insert;
DROP TABLE IF EXISTS codigos_descuento;
DELETE FROM productos WHERE nombre = 'Producto Test';

En el siguiente artículo veremos los triggers AFTER INSERT para ejecutar acciones después de una inserción.

Escrito por Eduardo Lázaro