【问题标题】:MySQL UPDATE BEFORE trigger puzzlerMySQL UPDATE BEFORE 触发谜题
【发布时间】:2011-11-05 02:04:59
【问题描述】:

我有一个包含 IsDirty 列的表,我希望在更新行时将其设为“1”,但我也希望能够将 IsDirty 标志显式设置回“0”。所以我创建了一个触发器:

FOR EACH ROW
BEGIN

 IF NEW.IsDirty = 0 AND OLD.IsDirty=1 THEN
  SET NEW.IsDirty = 0;
 ELSE SET NEW.IsDirty = 1;
 END IF; 

END;

使用此触发器,更新任何列会将 IsDirty 列设置为 1。我还可以“UPDATE table_name SET IsDirty = 0 WHERE xxx=123”——非常适合“关闭” IsDirty。

但如果我连续执行两次(“UPDATE table_name SET IsDirty = 0 WHERE xxx=123”),它会将 IsDirty 再次设置为 1。再做一次,将其设置为 0。然后来回切换,每次都进行切换。看着我的触发器,我可以看到会发生什么。所以我把它改成了这样:

FOR EACH ROW
BEGIN

IF NEW.IsDirty = 0 AND OLD.IsDirty=1 THEN
 SET NEW.IsDirty = 0;
ELSEIF NEW.IsDirty = 0 AND OLD.IsDirty=0 THEN
 SET NEW.IsDirty = 0;
ELSE SET NEW.IsDirty = 1;
END IF; 

但现在更新 IsDirty 以外的任何列不再将 IsDirty 设置为 1。现在将其设置为 1 的唯一方法是显式更新 IsDirty 列。

我做错了什么?我只想在更新列时打开 IsDirty,并且还能够将其关闭,甚至连续两次并让它保持关闭状态。

感谢您的帮助!

【问题讨论】:

    标签: mysql triggers


    【解决方案1】:

    嗯,我最终做了这个触发器有点不同。与其纠结于尝试确定更新是否只是行上数据的更改,还是仅更改 IsDirty 标志,还是两者都有,都没有……

    我最终将要求更改为:“如果您想重置 IsDirty 标志;即,将其设置为零 - 然后在更新语句中将其设置为 -1”。所以它非常明确和清晰。

    所以现在触发器看起来像这样:

    BEGIN
      SET NEW.EffectiveDate = current_timestamp;
      IF NEW.IsDirty = -1 THEN
        BEGIN
          SET NEW.IsDirty = 0;
        END;
      ELSE
        SET NEW.IsDirty = 1;
      END IF;
    END    
    

    想要重置 IsDirty 列的 UPDATE 语句如下例所示:

    UPDATE task_set SET IsDirty = -1 WHERE CategoryID = 20
    

    【讨论】:

      猜你喜欢
      • 2013-01-24
      • 2011-01-21
      • 1970-01-01
      • 2021-11-03
      • 1970-01-01
      • 2021-11-25
      • 2018-05-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多