Mysql 如果值已更改,则使用触发器插入行

Mysql 如果值已更改,则使用触发器插入行,mysql,sql,triggers,Mysql,Sql,Triggers,我有下面的“狗”表 如果更改了一个或多个值,例如updatedogs SET Name=“Bud”,Color=“redish”,Age=8,其中id=2,我想在另外两个表中插入几行: INSERT INTO audits(id,auditTable,auditPK,dateTime) VALUES (0,'dogs',2,NOW()); INSERT INTO auditFields(id,auditsId,changeField,oldValue,newValue) VALUES (0,12

我有下面的“狗”表

如果更改了一个或多个值,例如
updatedogs SET Name=“Bud”,Color=“redish”,Age=8,其中id=2,我想在另外两个表中插入几行:

INSERT INTO audits(id,auditTable,auditPK,dateTime) VALUES (0,'dogs',2,NOW());
INSERT INTO auditFields(id,auditsId,changeField,oldValue,newValue) VALUES (0,123,'Color','Red','Redish');
INSERT INTO auditFields(id,auditsId,changeField,oldValue,newValue) VALUES (0,123,'Age',7,8);
auditsId是第一次插入的自动增量ID。请注意,没有为名称更改插入内容,因为它仍然是“Bud”。我正在考虑规范化auditTable和changeField,但不确定是否应该

这可能与触发器有关吗?如果是,怎么做?

试试这个

DELIMITER $$
CREATE TRIGGER tg_dogs_upd AFTER UPDATE ON dogs
FOR EACH ROW 
BEGIN
    SET @AID = 0;
    IF NEW.name <> OLD.name THEN
        IF @AID = 0 THEN
            INSERT INTO audits(auditTable,auditPK,`dateTime`) VALUES ('dogs', NEW.id, NOW());
            SELECT LAST_INSERT_ID() INTO @AID;
        END IF;
        INSERT INTO auditFields(auditsId,changeField,oldValue,newValue) VALUES (@AID,'Name',OLD.`name`,NEW.`name`);
    END IF;
    IF NEW.color <> OLD.color THEN
        IF @AID = 0 THEN
            INSERT INTO audits(auditTable,auditPK,`dateTime`) VALUES ('dogs', NEW.id, NOW());
            SELECT LAST_INSERT_ID() INTO @AID;
        END IF;
        INSERT INTO auditFields(auditsId,changeField,oldValue,newValue) VALUES (@AID,'Color',OLD.color,NEW.color);
    END IF;
    IF NEW.size <> OLD.size THEN
        IF @AID = 0 THEN
            INSERT INTO audits(auditTable,auditPK,`dateTime`) VALUES ('dogs', NEW.id, NOW());
            SELECT LAST_INSERT_ID() INTO @AID;
        END IF;
        INSERT INTO auditFields(auditsId,changeField,oldValue,newValue) VALUES (@AID,'Size',OLD.size,NEW.size);
    END IF;
    IF NEW.hair <> OLD.hair THEN
        IF @AID = 0 THEN
            INSERT INTO audits(auditTable,auditPK,`dateTime`) VALUES ('dogs', NEW.id, NOW());
            SELECT LAST_INSERT_ID() INTO @AID;
        END IF;
        INSERT INTO auditFields(auditsId,changeField,oldValue,newValue) VALUES (@AID,'Hair',OLD.hair,NEW.hair);
    END IF;
    IF NEW.age <> OLD.age THEN
        IF @AID = 0 THEN
            INSERT INTO audits(auditTable,auditPK,`dateTime`) VALUES ('dogs', NEW.id, NOW());
            SELECT LAST_INSERT_ID() INTO @AID;
        END IF;
        INSERT INTO auditFields(auditsId,changeField,oldValue,newValue) VALUES (@AID,'Age',OLD.age,NEW.age);
    END IF;
END$$

DELIMITER ;
分隔符$$
更新狗后创建触发tg_狗_upd
每行
开始
设置@AID=0;
如果NEW.name OLD.name,则
如果@AID=0,则
将值('dogs',NEW.id,NOW())插入审计(auditTable,auditPK,`dateTime`)中;
选择最后一个插入ID()到@AID;
如果结束;
在auditFields(auditsId、changeField、oldValue、newValue)中插入值(@AID、'Name',OLD.'Name',NEW.'Name`);
如果结束;
如果是新的。颜色是旧的。颜色是新的
如果@AID=0,则
将值('dogs',NEW.id,NOW())插入审计(auditTable,auditPK,`dateTime`)中;
选择最后一个插入ID()到@AID;
如果结束;
将值(@AID,'Color',OLD.Color,NEW.Color)插入到auditFields(auditsId,changeField,oldValue,newValue)中;
如果结束;
如果是NEW.size OLD.size那么
如果@AID=0,则
将值('dogs',NEW.id,NOW())插入审计(auditTable,auditPK,`dateTime`)中;
选择最后一个插入ID()到@AID;
如果结束;
插入auditFields(auditsId、changeField、oldValue、newValue)值(@AID、'Size',OLD.Size,NEW.Size);
如果结束;
如果是新发,那么是旧发
如果@AID=0,则
将值('dogs',NEW.id,NOW())插入审计(auditTable,auditPK,`dateTime`)中;
选择最后一个插入ID()到@AID;
如果结束;
将值(@AID,'Hair',OLD.Hair,NEW.Hair)插入到auditFields(auditsId,changeField,oldValue,newValue)中;
如果结束;
如果是新的,老的,那么
如果@AID=0,则
将值('dogs',NEW.id,NOW())插入审计(auditTable,auditPK,`dateTime`)中;
选择最后一个插入ID()到@AID;
如果结束;
将值(@AID,'Age',OLD.Age,NEW.Age)插入auditFields(auditsId,changeField,oldValue,newValue)中;
如果结束;
结束$$
定界符;
更新:使用临时表的更简洁版本

DELIMITER $$
CREATE TRIGGER tg_dogs_upd AFTER UPDATE ON dogs
FOR EACH ROW 
BEGIN
    DROP TEMPORARY TABLE IF EXISTS tempAuditFields;
    CREATE TEMPORARY TABLE tempAuditFields(changeField VARCHAR(256),oldValue VARCHAR(256),newValue VARCHAR(256));
    IF NEW.name <> OLD.name THEN
        INSERT INTO tempAuditFields VALUES ('Name',OLD.`name`,NEW.`name`);
    END IF;
    IF NEW.color <> OLD.color THEN
        INSERT INTO tempAuditFields VALUES ('Color',OLD.color,NEW.color);
    END IF;
    IF NEW.size <> OLD.size THEN
        INSERT INTO tempAuditFields VALUES ('Size',OLD.size,NEW.size);
    END IF;
    IF NEW.hair <> OLD.hair THEN
        INSERT INTO tempAuditFields VALUES ('Hair',OLD.hair,NEW.hair);
    END IF;
    IF NEW.age <> OLD.age THEN
        INSERT INTO tempAuditFields VALUES ('Age',OLD.age,NEW.age);
    END IF;

    IF (SELECT COUNT(*) FROM tempAuditFields) > 0 THEN
        INSERT INTO audits(auditTable,auditPK,`dateTime`) VALUES ('dogs', NEW.id, NOW());
        SELECT LAST_INSERT_ID() INTO @AID;
        INSERT INTO auditFields(auditsId,changeField,oldValue,newValue)
        SELECT @AID,changeField,oldValue,newValue FROM tempAuditFields;
        DROP TEMPORARY TABLE tempAuditFields;
    END IF;
END$$

DELIMITER ;
分隔符$$
更新狗后创建触发tg_狗_upd
每行
开始
如果存在临时表字段,则删除临时表;
创建临时表tempAuditFields(changeField VARCHAR(256)、oldValue VARCHAR(256)、newValue VARCHAR(256));
如果NEW.name OLD.name,则
在tempAuditFields中插入值('Name',OLD.'Name',NEW.'Name`);
如果结束;
如果是新的。颜色是旧的。颜色是新的
在tempAuditFields中插入值('Color',OLD.Color,NEW.Color);
如果结束;
如果是NEW.size OLD.size那么
在tempAuditFields中插入值('Size',OLD.Size,NEW.Size);
如果结束;
如果是新发,那么是旧发
在tempAuditFields中插入值('Hair',OLD.Hair,NEW.Hair);
如果结束;
如果是新的,老的,那么
在tempAuditFields中插入值('Age',OLD.Age,NEW.Age);
如果结束;
如果(从tempAuditFields中选择COUNT(*)大于0,则
将值('dogs',NEW.id,NOW())插入审计(auditTable,auditPK,`dateTime`)中;
选择最后一个插入ID()到@AID;
插入到auditFields(auditsId、changeField、oldValue、newValue)
从tempAuditFields中选择@AID、changeField、oldValue、newValue;
删除临时表字段;
如果结束;
结束$$
定界符;
试试这个

DELIMITER $$
CREATE TRIGGER tg_dogs_upd AFTER UPDATE ON dogs
FOR EACH ROW 
BEGIN
    SET @AID = 0;
    IF NEW.name <> OLD.name THEN
        IF @AID = 0 THEN
            INSERT INTO audits(auditTable,auditPK,`dateTime`) VALUES ('dogs', NEW.id, NOW());
            SELECT LAST_INSERT_ID() INTO @AID;
        END IF;
        INSERT INTO auditFields(auditsId,changeField,oldValue,newValue) VALUES (@AID,'Name',OLD.`name`,NEW.`name`);
    END IF;
    IF NEW.color <> OLD.color THEN
        IF @AID = 0 THEN
            INSERT INTO audits(auditTable,auditPK,`dateTime`) VALUES ('dogs', NEW.id, NOW());
            SELECT LAST_INSERT_ID() INTO @AID;
        END IF;
        INSERT INTO auditFields(auditsId,changeField,oldValue,newValue) VALUES (@AID,'Color',OLD.color,NEW.color);
    END IF;
    IF NEW.size <> OLD.size THEN
        IF @AID = 0 THEN
            INSERT INTO audits(auditTable,auditPK,`dateTime`) VALUES ('dogs', NEW.id, NOW());
            SELECT LAST_INSERT_ID() INTO @AID;
        END IF;
        INSERT INTO auditFields(auditsId,changeField,oldValue,newValue) VALUES (@AID,'Size',OLD.size,NEW.size);
    END IF;
    IF NEW.hair <> OLD.hair THEN
        IF @AID = 0 THEN
            INSERT INTO audits(auditTable,auditPK,`dateTime`) VALUES ('dogs', NEW.id, NOW());
            SELECT LAST_INSERT_ID() INTO @AID;
        END IF;
        INSERT INTO auditFields(auditsId,changeField,oldValue,newValue) VALUES (@AID,'Hair',OLD.hair,NEW.hair);
    END IF;
    IF NEW.age <> OLD.age THEN
        IF @AID = 0 THEN
            INSERT INTO audits(auditTable,auditPK,`dateTime`) VALUES ('dogs', NEW.id, NOW());
            SELECT LAST_INSERT_ID() INTO @AID;
        END IF;
        INSERT INTO auditFields(auditsId,changeField,oldValue,newValue) VALUES (@AID,'Age',OLD.age,NEW.age);
    END IF;
END$$

DELIMITER ;
分隔符$$
更新狗后创建触发tg_狗_upd
每行
开始
设置@AID=0;
如果NEW.name OLD.name,则
如果@AID=0,则
将值('dogs',NEW.id,NOW())插入审计(auditTable,auditPK,`dateTime`)中;
选择最后一个插入ID()到@AID;
如果结束;
在auditFields(auditsId、changeField、oldValue、newValue)中插入值(@AID、'Name',OLD.'Name',NEW.'Name`);
如果结束;
如果是新的。颜色是旧的。颜色是新的
如果@AID=0,则
将值('dogs',NEW.id,NOW())插入审计(auditTable,auditPK,`dateTime`)中;
选择最后一个插入ID()到@AID;
如果结束;
将值(@AID,'Color',OLD.Color,NEW.Color)插入到auditFields(auditsId,changeField,oldValue,newValue)中;
如果结束;
如果是NEW.size OLD.size那么
如果@AID=0,则
将值('dogs',NEW.id,NOW())插入审计(auditTable,auditPK,`dateTime`)中;
选择最后一个插入ID()到@AID;
如果结束;
插入auditFields(auditsId、changeField、oldValue、newValue)值(@AID、'Size',OLD.Size,NEW.Size);
如果结束;
如果是新发,那么是旧发
如果@AID=0,则
将值('dogs',NEW.id,NOW())插入审计(auditTable,auditPK,`dateTime`)中;
选择最后一个插入ID()到@AID;
如果结束;
将值(@AID,'Hair',OLD.Hair,NEW.Hair)插入到auditFields(auditsId,changeField,oldValue,newValue)中;
如果结束;
如果是新的,老的,那么
如果@AID=0,则
将值('dogs',NEW.id,NOW())插入审计(auditTable,auditPK,`dateTime`)中;
选择最后一个插入ID()到@AID;
如果结束;
将值(@AID,'Age',OLD.Age,NEW.Age)插入auditFields(auditsId,changeField,oldValue,newValue)中;
如果结束;
结束$$
定界符;
更新:使用临时表的更简洁版本

DELIMITER $$
CREATE TRIGGER tg_dogs_upd AFTER UPDATE ON dogs
FOR EACH ROW 
BEGIN
    DROP TEMPORARY TABLE IF EXISTS tempAuditFields;
    CREATE TEMPORARY TABLE tempAuditFields(changeField VARCHAR(256),oldValue VARCHAR(256),newValue VARCHAR(256));
    IF NEW.name <> OLD.name THEN
        INSERT INTO tempAuditFields VALUES ('Name',OLD.`name`,NEW.`name`);
    END IF;
    IF NEW.color <> OLD.color THEN
        INSERT INTO tempAuditFields VALUES ('Color',OLD.color,NEW.color);
    END IF;
    IF NEW.size <> OLD.size THEN
        INSERT INTO tempAuditFields VALUES ('Size',OLD.size,NEW.size);
    END IF;
    IF NEW.hair <> OLD.hair THEN
        INSERT INTO tempAuditFields VALUES ('Hair',OLD.hair,NEW.hair);
    END IF;
    IF NEW.age <> OLD.age THEN
        INSERT INTO tempAuditFields VALUES ('Age',OLD.age,NEW.age);
    END IF;

    IF (SELECT COUNT(*) FROM tempAuditFields) > 0 THEN
        INSERT INTO audits(auditTable,auditPK,`dateTime`) VALUES ('dogs', NEW.id, NOW());
        SELECT LAST_INSERT_ID() INTO @AID;
        INSERT INTO auditFields(auditsId,changeField,oldValue,newValue)
        SELECT @AID,changeField,oldValue,newValue FROM tempAuditFields;
        DROP TEMPORARY TABLE tempAuditFields;
    END IF;
END$$

DELIMITER ;
分隔符$$
更新狗后创建触发tg_狗_upd
每行
开始
如果存在临时表字段,则删除临时表;
创建临时表tempAuditFields(changeField VARCHAR(256)、oldValue VARCHAR(256)、newValue VARCHAR(256));
如果NEW.name OLD.name,则
在tempAuditFields中插入值('Name',OLD.'Name',NEW.'Name`);