2016-08-10 47 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 ;