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