1

我有一个 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'

以上触发了更新触发器,但是在统计表中,对于最后一次更新查询,已完成的小时数显示为 0。

有更好的触发器知识的人可以帮助我吗?

谢谢,

标记

4

2 回答 2

1

Solution was:

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//
于 2012-11-08T11:56:09.180 回答
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。

这次有意义吗?

于 2012-11-07T17:47:40.720 回答