MySQL不具备必要的语句级触发器在标准的方式来实现这一点,但是我创建了以下解决方法。在before触发器中,在第一行之前,它会检查ROW_COUNT是否为-1,这意味着尚未插入行,并将默认值1设置为@x。然后可以在更新后使用@x。在before触发器中,在第二行之前,当它检查ROW_COUNT时,它现在是1或更高,如果你的after触发器插入了更多的行,那么它不再是-1,所以初始化不会再次运行。
DROP TRIGGER record_before_update;
DELIMITER $$
CREATE TRIGGER record_before_update
BEFORE UPDATE ON record
FOR EACH ROW
BEGIN
DECLARE y INT;
SET y = (SELECT ROW_COUNT());
IF y = -1 THEN
SET @x = 1;
END IF;
END$$
DELIMITER ;
DROP TRIGGER record_after_update;
DELIMITER $$
CREATE TRIGGER record_after_update
AFTER UPDATE ON record
FOR EACH ROW
BEGIN
#use @x in something
END$$
DELIMITER ;
注意,在您的交易使用的触发将需要语句之前任何其他更新被称为否则ROW_COUNT不会是-1。而这个例子是为了更新,你需要插入触发器的同样的东西。
如果有助于看到一个真实的例子,这里是我如何使用它。当不同“区域”中的一堆行有更新时,它只会通过维护已经更新的区域阵列来更新单个区域。
DROP TRIGGER record_before_update;
DELIMITER $$
CREATE TRIGGER record_before_update
BEFORE UPDATE ON record
FOR EACH ROW
BEGIN
DECLARE y INT;
SET y = (SELECT ROW_COUNT());
IF y = -1 THEN
SET @x = NULL;
END IF;
END$$
DELIMITER ;
DROP TRIGGER record_after_update;
DELIMITER $$
CREATE TRIGGER record_after_update
AFTER UPDATE ON record
FOR EACH ROW
BEGIN
DELETE FROM record_change where record_id = NEW.id;
INSERT INTO record_change(record_id, number) VALUES(NEW.id, @x);
IF @x IS NULL OR FIND_IN_SET(NEW.zone_id, @x) = 0 THEN
SET @x = CONCAT_WS(',', @x, NEW.zone_id);
DELETE FROM zone_change where zone_id = NEW.zone_id;
INSERT INTO zone_change(zone_id, number) VALUES(NEW.zone_id, @x);
END IF;
END$$
DELIMITER ;
'declare'应该在'BEGIN'语句之后。不建议在触发器内调用“Procedure”。 http://dev.mysql.com/doc/refman/5.5/en/stored-program-restrictions.html – Riad
是的,我知道它应该在之后。我问是否有任何方法可以做到这一点... – user3509357