2017-03-20 68 views
3

我有order屬性的測試表。當order更改它的值我需要重新計算表中的所有order值。我有以下觸發:Mysql觸發器返回1442錯誤

DELIMITER $$ 

USE `testing`$$ 

DROP TRIGGER /*!50032 IF EXISTS */ `UpdateOrder`$$ 

CREATE 
    /*!50017 DEFINER = 'root'@'localhost' */ 
    TRIGGER `UpdateOrder` AFTER UPDATE ON `upd_tst` 
    FOR EACH ROW BEGIN 
    IF (OLD.order > NEW.order) THEN 
     UPDATE `upd_tst` t SET t.`order` = t.`order` + 1 WHERE t.`order` < OLD.order AND t.`order` >= NEW.order AND t.id <> OLD.id; 
    ELSEIF (OLD.order < NEW.order) THEN 
     UPDATE `upd_tst` t SET t.`order` = t.`order` - 1 WHERE t.`order` > OLD.order AND t.`order` <= NEW.order AND t.id <> OLD.id; 
    END IF; 
    END; 
$$ 

DELIMITER ; 

當我嘗試更新的任何項目,我得到NEX錯誤:

Executed SQL Statement : update `testing`.`upd_tst` set `order`='3' where `id`='3' 
Error Number : 1442 
Error Message: Can't update table 'upd_tst' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. 

我怎麼能解決這個問題?我只需要使用觸發器。

在postgresql中,我可以在觸發器內使用這個條件WHEN (pg_trigger_depth() = 0)。在mysql中是否有這樣的東西?

+2

想想看,如果你更新後觸發有更新您'll有一個無限循環 – Mihai

+0

要麼重新計算上使用的飛行只是爲了重新計算 – Mihai

+0

我認爲我能避免無限循環的另一個表這種情況'AND t.id <> OLD.id' –

回答

0

解決方案:讓它BEFORE UPDATE ON觸發 - 所以你可以設置/在觸發SQL更新的字段值:

DELIMITER $$ 
USE `testing`$$ 
DROP TRIGGER /*!50032 IF EXISTS */ `UpdateOrder`$$ 
CREATE 
    /*!50017 DEFINER = 'root'@'localhost' */ 
    TRIGGER `UpdateOrder` BEFORE UPDATE ON `upd_tst` 
    FOR EACH ROW BEGIN 
    IF (OLD.order > NEW.order) THEN 
     SET NEW.order = NEW.order` + 1; 
    ELSEIF (OLD.order < NEW.order) THEN 
     SET NEW.order = NEW.order - 1; 
    END IF; 
    END; 
$$ 
DELIMITER ; 

原因:您不能更新/刪除/插入到表觸發器被調用的位置:

Within a stored function or trigger, it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.

這樣做會生成錯誤1442:

Error Code: 1442 
Can't update table 'MyTable' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.