首页 > 解决方案 > MySQL 更新触发器正在更新表上的每条记录

问题描述

我正在为 MySQL 中的审计表开发触发器。有 2 个表和 2 个单独的触发器:clients 和 aud_clients

一个触发器是 AFTER INSERT ON 客户端,另一个触发器是 AFTER UPDATE ON 客户端。基本上每次将一条记录插入客户端时,也应将一条记录插入 aud_clients,如果它是客户端上的 UPDATE,则 aud_clients 上的更新应将旧数据放入 old_[Whatever] 字段,将新数据放入 new_[Whatever]字段。

操作本身正在工作,问题是,在客户端上进行更新后, aud_clients 上的每条记录都会成为新更新的记录。

正在发生的事情的输出示例

code old_name   old_date              old_credit   new_name    new_date       new_credit
10  jello   2019-11-28 19:38:09 2342    100234.20   jam   2019-11-28 19:41:23   11145580    
10  jello   2019-11-28 19:38:09 2342    100234.20   jam   2019-11-28 19:41:23   11145580
10  jello   2019-11-28 19:38:09 2342    100234.20   jam   2019-11-28 19:41:23   11145580

这是更新触发器

DELIMITER //

CREATE TRIGGER aud_upd AFTER UPDATE ON clientes
FOR EACH ROW
BEGIN
        UPDATE aud_clientes SET
            aud_clientes.cod_cliente = NEW.Cod_cliente,
            aud_clientes.nombre_antes = OLD.nombre_cliente,
            aud_clientes.nombre_despues = NEW.nombre_cliente,
            aud_clientes.telefono_antes = OLD.telefono,
            aud_clientes.telefono_despues = NEW.telefono,
            aud_clientes.credito_antes = OLD.credito_max,
            aud_clientes.credito_despues = NEW.credito_max,
            aud_clientes.fecha_creacion_antes = OLD.fecha_creacion,
            aud_clientes.fecha_creacion_despues = NEW.fecha_creacion,
            aud_clientes.tipo_transaccion = 'UPD',
            aud_clientes.modificado_por = current_user(),
            aud_clientes.fecha = current_timestamp();
END//

DELIMITER ;

INSERT 触发器按预期工作,但如果您想查看它:

DELIMITER //

CREATE TRIGGER aud_ins AFTER INSERT ON clientes
FOR EACH ROW
BEGIN
        INSERT INTO aud_clientes (
            aud_clientes.cod_cliente,
            aud_clientes.nombre_antes,
            aud_clientes.nombre_despues,
            aud_clientes.telefono_antes,
            aud_clientes.telefono_despues,
            aud_clientes.credito_antes,
            aud_clientes.credito_despues,
            aud_clientes.fecha_creacion_antes,
            aud_clientes.fecha_creacion_despues,
            aud_clientes.tipo_transaccion,
            aud_clientes.modificado_por,
            aud_clientes.fecha
        ) VALUES (
            NEW.cod_cliente,
            null,
            NEW.nombre_cliente,
            null,
            NEW.telefono,
            null,
            NEW.credito_max,
            null,
            NEW.fecha_creacion,
            'INS',
            current_user(),
            current_timestamp()
        );
END//

DELIMITER ;

最后,如果要查看表结构:

CREATE TABLE clientes (
    cod_cliente INT NOT NULL,
    nombre_cliente VARCHAR(100) NOT NULL,
    fecha_creacion datetime not null,
    telefono VARCHAR(100) NOT NULL,
    credito_max DOUBLE(10, 2),
    PRIMARY KEY (cod_cliente)
    );
    commit;

CREATE TABLE aud_clientes (
    cod_cliente INT,
    nombre_antes VARCHAR(100),
    fecha_creacion_antes datetime,
    telefono_antes VARCHAR(100),
    credito_antes DOUBLE(10,2),
    nombre_despues VARCHAR(100),
    fecha_creacion_despues datetime,
    telefono_despues VARCHAR(100),
    credito_despues DOUBLE(10,2),
    modificado_por varchar(100),
    fecha datetime,
    tipo_transaccion varchar(100)
    );
    commit;

请注意,无需在 aud_clientes 表上建立关系或键。我曾经在非空 auto_increment 上将 cod_cliente 作为其主要,但没有更新记录(这可能是因为它在尝试将相同的代码提供给多个记录时遇到错误)所以我删除了它。

标签: mysqlsqltriggerssql-update

解决方案


推荐阅读