我正在尝试创建一个触发器,当月列为 12 时,该触发器将自动将年列增加 1,然后清空月列。但是我不太了解触发器,而且我在尝试中让自己感到困惑,所以我希望有人可以查看这段代码,看看它是否可以工作或提出改进建议:
CREATE TRIGGER aging BEFORE UPDATE ON dogs
FOR EACH ROW
DELETE FROM dogs WHERE month = 12;
UPDATE year SET year = year+1;
谢谢!
需要指出两点...
首先,触发器显然是您想要做的错误选择。不仅因为可以通过根据出生日期即时计算年龄来避免触发因素。而且,因为触发器只影响受相应语句影响的行。不要被FOR EACH ROW
. 你写了类似的东西
UPDATE table SET whatever = whatever WHERE month = 12;
并且月 = 12 为真的所有行都会受到影响。您似乎想要做的是更新整个表以检查某些行中您的条件是否为真。这不仅是一场性能噩梦,而且您还被限制为每个表一个触发器(每个事件)。这意味着您可以拥有 ie oneBEFORE UPDATE
和 1AFTER UPDATE
但不能拥有 2 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 @@
将正确更新列。
我以前从未创建过触发器,但我只是通读了文档。这是我的尝试...
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;
@@