MySQL触发老化

时间:2013-09-12 17:50:32

标签: mysql sql triggers

我正在尝试创建一个触发器,当月份列为12时,将自动将年份列增加1,然后清空月份列。 但是我并不理解触发器,我在尝试中让自己感到困惑,所以我希望有人可以查看这段代码,看看它是否可行或建议改进:

CREATE TRIGGER aging BEFORE UPDATE ON dogs
FOR EACH ROW
DELETE FROM dogs WHERE month = 12;
UPDATE year SET year = year+1;

谢谢!

2 个答案:

答案 0 :(得分:2)

要指出两件事......

首先,对于您想要做的事情,触发器显然是错误的选择。不仅因为可以通过基于日期的出生来计算动态的年龄来避免触发。但是,因为触发器仅影响受相应语句影响的行。不要被FOR EACH ROW愚弄。你写了像

这样的东西
UPDATE table SET whatever = whatever WHERE month = 12;

并且month = 12为true的所有行都会受到影响。您似乎想要做的是更新整个表以检查在某些行中您的条件是否为真。这不仅是一场性能噩梦,而且每张桌子也限制一次触发(每个事件)。这意味着您可以拥有一个BEFORE UPDATE和一个AFTER UPDATE但不是BEFORE UPDATE

要注意的第二件事是,您不能在UPDATE触发器中发出UPDATE语句。这会导致无限循环:)

而是使用别名NEWOLDNEW引用UPDATE语句给出的列的值,OLD引用UPDATE语句执行之前的列的值。

在你的情况下(虽然现在很清楚,在这种情况下你不应该使用触发器),你可以像这样编写触发器:

鉴于此初步陈述

UPDATE myTable SET whatever = whatever;

更新整个表,此触发器

DROP TRIGGER IF EXISTS [whatever you call this thing];

DELIMITER @@
CREATE TRIGGER aging BEFORE UPDATE ON dogs
FOR EACH ROW
    IF (month = 12) THEN /*month refers to the column here, not a variable like in Gordon's answer*/
       SET NEW.year = OLD.year+1;
       SET NEW.month = 1;
    END IF;
END @@

会正确更新列。

答案 1 :(得分:0)

我之前从未创建过触发器,但我只是阅读了文档。这是我的尝试......

DELIMITER ||
DROP TRIGGER ID EXISTS [whatever you call this thing]
||

DELIMITER @@
CREATE TRIGGER aging BEFORE UPDATE ON dogs
FOR EACH ROW
    DECLARE month integer;
    IF (month = 12) THEN
    -- DELETE FROM dogs WHERE month = 12;
    -- this will delete the record; probably not what you want
       UPDATE year SET year = year+1;
       UPDATE month SET month = NULL;
    END IF;
END;
@@