我正在尝试创建一个触发器,当月份列为12时,将自动将年份列增加1,然后清空月份列。 但是我并不理解触发器,我在尝试中让自己感到困惑,所以我希望有人可以查看这段代码,看看它是否可行或建议改进:
CREATE TRIGGER aging BEFORE UPDATE ON dogs
FOR EACH ROW
DELETE FROM dogs WHERE month = 12;
UPDATE year SET year = year+1;
谢谢!
答案 0 :(得分:2)
要指出两件事......
首先,对于您想要做的事情,触发器显然是错误的选择。不仅因为可以通过基于日期的出生来计算动态的年龄来避免触发。但是,因为触发器仅影响受相应语句影响的行。不要被FOR EACH ROW
愚弄。你写了像
UPDATE table SET whatever = whatever WHERE month = 12;
并且month = 12为true的所有行都会受到影响。您似乎想要做的是更新整个表以检查在某些行中您的条件是否为真。这不仅是一场性能噩梦,而且每张桌子也限制一次触发(每个事件)。这意味着您可以拥有一个BEFORE UPDATE
和一个AFTER UPDATE
但不是BEFORE UPDATE
。
要注意的第二件事是,您不能在UPDATE触发器中发出UPDATE语句。这会导致无限循环:)
而是使用别名NEW
和OLD
。 NEW
引用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;
@@