You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL触发器更新almacen表异常及1175错误求助

解决触发器更新almacen表的问题

问题现象

在registro_producto表插入数据后,触发器更新almacen表时出现数据重复/新增产品数据重复问题,同时触发以下错误:

Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. To disable safe mode, toggle the option in Preferences -> SQL Editor and reconnect.

表结构代码

create table registro_producto(
id_producto int(5) not null,
id_proveedor int(5) not null,
    id_trabajador int(5) not null,
    nombre_producto varchar(20) not null,
    u_medida varchar(20) not null,
    cantidad_producto decimal(8,3) not null,
    clase_producto varchar(20) not null,
constraint PK_ID_Producto primary key(id_producto),
constraint FK_Proveedor1 foreign key (id_proveedor) references proveedor(id_proveedor),
    constraint FK_ID_Trabajador1 foreign key(id_trabajador) references trabajador(id_trabajador),
    constraint CK_Clase_Producto check (clase_Producto in ('perecible','no perecible'))
);

create table almacen(
    id_almacen int(5) not null,
        id_producto int(5) not null,
    fecha_entrada date not null,
    cantidad_total decimal(8,3) not null,
    cantidad_restante decimal(8,3),
    constraint pk_id_almacen primary key (id_almacen),
    constraint fk_id_producto foreign key (id_producto) references registro_producto(id_producto)
);

原触发器代码

DELIMITER //
CREATE TRIGGER tr_actualizar_almacen_registro_producto
AFTER INSERT ON registro_producto
FOR EACH ROW
BEGIN
    -- Actualizar cantidad total y restante del producto
    UPDATE almacen
    SET cantidad_total = cantidad_total + NEW.cantidad_producto,
        cantidad_restante = cantidad_restante + NEW.cantidad_producto
    WHERE id_producto = NEW.id_producto;
    
    -- Actualizar cantidad restante del producto en base a las entradas anteriores
    UPDATE almacen a
    INNER JOIN (
        SELECT id_producto, SUM(cantidad_producto) AS cantidad_total
        FROM registro_producto
        GROUP BY id_producto
    ) r ON a.id_producto = r.id_producto
    SET a.cantidad_restante = r.cantidad_total - a.cantidad_total;
END//
DELIMITER ;

问题分析与解决方案

1. 1175错误原因与修复

原触发器中第二个UPDATE语句没有指定针对当前插入产品的过滤条件,会尝试更新整个almacen表,触发MySQL安全更新模式的限制。同时该语句的逻辑完全错误,会导致cantidad_restante计算混乱,直接删除即可。

2. 数据重复问题修复

原触发器未处理产品首次入库的场景:当almacen中无对应产品记录时,第一个UPDATE不会执行,后续也没有插入逻辑,若重复插入同产品会导致数据异常。需增加判断,无记录时插入新条目。

修改后的触发器代码

DELIMITER //
CREATE TRIGGER tr_actualizar_almacen_registro_producto
AFTER INSERT ON registro_producto
FOR EACH ROW
BEGIN
    -- 累加已有产品的库存总量和剩余量
    UPDATE almacen
    SET cantidad_total = cantidad_total + NEW.cantidad_producto,
        cantidad_restante = cantidad_restante + NEW.cantidad_producto
    WHERE id_producto = NEW.id_producto;
    
    -- 若未找到对应产品记录(首次入库),插入新库存条目
    IF ROW_COUNT() = 0 THEN
        INSERT INTO almacen(id_producto, fecha_entrada, cantidad_total, cantidad_restante)
        VALUES(NEW.id_producto, CURDATE(), NEW.cantidad_producto, NEW.cantidad_producto);
    END IF;
END//
DELIMITER ;

临时关闭安全更新模式(可选)

若仍触发1175错误,可在执行触发器前临时关闭安全模式:

SET SQL_SAFE_UPDATES = 0;

操作完成后建议重新开启:

SET SQL_SAFE_UPDATES = 1;

内容的提问来源于stack exchange,提问作者Hilurex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 08:55:03