1

実行中の UPDATE クエリに基づいて、時間を統計テーブルに更新する MySQL トリガーがあります。

トリガーは次のとおりです。

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();

同じテーブルを更新する上記と同様の別のクエリがありますが、checked completed_hours が null ではないという少しの違いがあります。クエリは次のとおりです。

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 として表示されます。

私を助けることができるトリガーのより良い知識を持っている人はいますか?

ありがとう、

マーク

4

2 に答える 2

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//
于 2012-11-08T11:56:09.180 に答える
0

INSERT では、2 つの行操作 (1 つの減算と 1 つの加算) を実行しています。

重複がある場合、ON DUPLICATE KEY は 2 回実行されます。1 回は減算用、もう 1 回は加算用です。

2 番目のクエリでは、completed_hours の値が変更されていないため、OLD と NEW は同じになります。値を加算してから値を減算すると、0 になります。

多分 :)

そうでない場合は、どこかで NULL に問題があります。

編集:私が明確だったかどうかはわかりません。より明確にするための試みを次に示します。

2 回目の更新を行います。

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

更新する user_hours 行が 1 つ見つかったとします。これは次のようになります。

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

次に、2 つの 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 部分を 2 回実行し、効果的に次のことを行います。

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

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

私が言おうとしていた点は、最後の 2 つは互いに相殺する必要があるということです。元の hour_statistics.completed_hours が 0 だった場合、トリガーが起動すると 0 になります。

今回は理にかなっていますか?

于 2012-11-07T17:47:40.720 に答える