UPDATE上的MySQL触发器不会将小时数据发送到统计表

时间:2012-11-07 15:03:15

标签: mysql eventtrigger

我有一个MySQL触发器,可以根据正在运行的UPDATE查询将小时更新为统计表。

触发器是:

DELIMITER //

CREATE TRIGGER update_stats AFTER UPDATE ON user_hours 

FOR EACH ROW

BEGIN

  IF NEW.hours_committed = 'completed' THEN


    INSERT INTO hours_statistics (user_id, opportunity_id, completed_hours) VALUES

      (OLD.user_id, OLD.opportunity_id, -OLD.completed_hours),

      (NEW.user_id, NEW.opportunity_id, +NEW.completed_hours)

    ON DUPLICATE KEY UPDATE

      completed_hours = completed_hours + VALUES(completed_hours);


  END IF;

END//

工作查询:

UPDATE user_hours JOIN user_calendar USING (user_calendar_id, opportunity_id)
SET    user_hours.completed_hours = agreed_hours,
       user_hours.hours_committed = 'completed'
WHERE  user_hours.hours_committed = 'accepted' 
   AND user_hours.completed_hours IS NULL
   AND user_calendar.date_start = CURRENT_DATE();

我有另一个类似于上面的查询,它更新了同一个表,但检查的completed_hours不为空。查询如下:

UPDATE user_hours JOIN user_calendar USING (user_calendar_id, opportunity_id)
SET    user_hours.hours_committed = 'completed'
WHERE  user_hours.hours_committed = 'accepted' 
   AND user_hours.completed_hours IS NOT NULL
   AND user_calendar.date_start = '2012-08-23'

上面会触发更新触发器,但是在统计信息表中,completed_hours显示为上次更新查询的0。

对触发器有更好了解的人能够帮助我吗?

谢谢,

标记

2 个答案:

答案 0 :(得分:1)

解决方案是:

DELIMITER //

CREATE TRIGGER update_stats AFTER UPDATE ON user_hours 

FOR EACH ROW

BEGIN

IF  NEW.hours_committed =  'completed'  THEN
IF OLD.completed_hours IS NULL THEN
BEGIN
INSERT INTO hours_statistics (user_id,opportunity_id,completed_hours)
VALUES
(OLD.user_id, OLD.opportunity_id, -OLD.completed_hours),
(NEW.user_id, NEW.opportunity_id, +NEW.completed_hours)
ON DUPLICATE KEY UPDATE
completed_hours = completed_hours + VALUES(completed_hours);
END;
ELSE
INSERT INTO hours_statistics (user_id,opportunity_id,completed_hours)
VALUES
(NEW.user_id, NEW.opportunity_id, +NEW.completed_hours)
ON DUPLICATE KEY UPDATE
completed_hours = completed_hours + VALUES(completed_hours);
END IF;
END  IF;


END//

答案 1 :(得分:0)

在INSERT中,你正在做两行操作 - 一次减法和一次加法。

当你有副本时,ON DUPLICATE KEY将运行两次 - 一次用于减法,一次用于加法。

在第二个查询中,completed_hours没有更改的值,因此OLD和NEW将是相同的。您将添加该值,然后减去该值,产生0。

也许:)。

如果没有,你在某处遇到NULL问题。

编辑:我不确定我是否清楚。这是一个更明确的尝试:

您进行第二次更新:

UPDATE user_hours JOIN user_calendar USING (user_calendar_id, opportunity_id)
SET    user_hours.hours_committed = 'completed' ...

假设这样找到一个要更新的user_hours行,如下所示:

user_id = 1
opportunity_id = 2
hours_committed = 'accepted' 
completed_hours = 10

然后它会触发触发器,它想要运行两个INSERTS:

INSERT INTO hours_statistics (user_id, opportunity_id, completed_hours) VALUES (1,2,-10)

INSERT INTO hours_statistics (user_id, opportunity_id, completed_hours) VALUES (1,2,+10)

如果违反了UNIQUE KEY,它将运行ON DUPLICATE KEY部分两次,有效地执行:

UPDATE hour_statistics set completed_hours = completed_hours + -10 WHERE...

UPDATE hour_statistics set completed_hours = completed_hours + 10 WHERE...

我试图提出的观点是,最后两个应该相互抵消。如果原始的hour_statistics.completed_hours为0,则触发器触发后它将为0。

这次有意义吗?