2016-08-10 26 views
2

好吧,伙计们,我找不到这个地方,但也许我只是不知道如何看。我使用的触发器为每一行调用一个过程,但是我想在FOR EACH ROW之前插入一些DECLARE语句。之所以这样,是因为我想在LOOP之前声明一些东西(对于每一行),所以我最终并没有对每一行都反复地声明同样的事情。Mysql触发器在循环之前声明

任何人都知道该怎么做?它甚至有可能吗?

这里下了扳机是如何看起来像:

delimiter $$ 
CREATE TRIGGER tr_inscricao_insert 
    AFTER INSERT ON tbl_inscricao 

    DECLARE ra_current INT; 
    DECLARE done INT DEFAULT FALSE; 

FOR EACH row 
BEGIN 
    CALL pr_atualizar_creditos(new.ra); 
END$$ 
delimiter ; 
+1

'declare'应该在'BEGIN'语句之后。不建议在触发器内调用“Procedure”。 http://dev.mysql.com/doc/refman/5.5/en/stored-program-restrictions.html – Riad

+0

是的,我知道它应该在之后。我问是否有任何方法可以做到这一点... – user3509357

回答

0

您可以从一个存储过程,其中包括声明部分,并从触发器调用再添一层,命名为您的存储过程。 一些灵感看到这个线程: Calling a Stored Procedure in a Stored Procedure in MySQL

+0

我没有得到这是如何帮助我的问题。我想在FOR EACH ROW之前做一些DECLARE语句。我希望这个语句每个触发器只发生一次,而不是每一行发生一次(因为触发器的其余部分会发生)。 – user3509357

0

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 ;