首页 > 解决方案 > 如果值没有改变,SQL 触发器更新记录而不是插入

问题描述

我试图实现一个 SQL 触发器,如果​​一列的值发生变化,它将更新而不是插入。

示例表

Id | Name | Income | Date
11   John   10000    2019-02-01
11   John   15000    2019-02-02

该表没有主键,因为它将有多个相同 ID 的记录,每个记录都有不同的日期。如果收入发生变化,我想要节省一些空间是更新而不是插入......例如,如果下一条记录将是:

11  John  15000  2019-02-03

我希望触发器更新 DATE 而不是在表上创建新记录。所以它最终会像:

11   John   10000    2019-02-01
11   John   15000    2019-02-03  <-- Changed!

数据来自记录当天收入的每小时表......并且在一天结束时,将每小时表上的所有记录大量插入到收入表中以保留历史记录。

我尝试了以下触发器,但它没有工作,因为它会锁定。

DELIMITER //
CREATE TRIGGER before_insert_income
    BEFORE INSERT ON income_30
    FOR EACH ROW
BEGIN
    IF NEW.income = (select income from income_30 where ID=NEW.ID and date=(select max(date) from income_30)) THEN
        UPDATE income_30 set date = NEW.date where ID=NEW.ID;
END IF;
END; //
DELIMITER ;

我还考虑执行 UPDATE 而不是 INSERT 并执行一个相反的触发器,如果​​收入发生变化,将插入一条新记录,但我不知道我可以将哪个列作为更新的主要列。

如果这是一个愚蠢的问题,我很抱歉,但它困扰了我一段时间。

非常感谢!

标签: mysqlsqltriggersinsert

解决方案


如果您只关心节省空间,我认为您应该只删除上个月的收入记录,然后再尝试插入相同金额的新收入。

DELIMITER //
CREATE TRIGGER before_insert_income
    BEFORE INSERT ON income_30
    FOR EACH ROW
BEGIN
    IF NEW.income = (select income from income_30 where ID=NEW.ID and date=(select max(date) from income_30)) THEN
       DELETE FROM income_30 where id=NEW.id and date=(select max(date) from income_30);

END IF;
END; //
DELIMITER;

推荐阅读