2014-10-06 32 views
3

我有2個類似的表,例如A和B. 我想複製A到B中的插入,以及B到A中的插入來集成兩個用戶系統。我在每一個「後插入觸發器」配置。例如:鏡像表:觸發器,死鎖和隱式提交

DELIMITER $$ 
CREATE DEFINER = `root`@`localhost` TRIGGER 
`after_A_INSERT` 
AFTER INSERT ON `A` 
FOR EACH ROW BEGIN 
INSERT INTO `B` 
SET `id` = NEW.`id`,`name` = NEW.`name`; 
END$$ 
DELIMITER ; 

DELIMITER $$ 
CREATE DEFINER = `root`@`localhost` TRIGGER 
`after_B_INSERT` 
AFTER INSERT ON `B` 
FOR EACH ROW BEGIN 
INSERT INTO `A` 
SET `id` = NEW.`id`,`name` = NEW.`name`; 
END$$ 
DELIMITER ; 

如果我在一個插入,觸發器調用乙插入件,但該插入物在乙執行觸發和發生死鎖避免無限循環。

我試着編輯觸發器在執行INSERT之前刪除另一個表觸發器,然後在它之後再次創建它。示例:

DELIMITER $$ 
CREATE DEFINER = `root`@`localhost` TRIGGER 
`after_B_INSERT` 
AFTER INSERT ON `B` 
FOR EACH ROW BEGIN 
DROP TRIGGER IF EXISTS `after_A_INSERT`; 
INSERT INTO `A` 
SET `id` = NEW.`id`, `name` = NEW.`name`; 
/* And CREATE again here */ 
END$$ 
DELIMITER ; 

但是,CREATE是一種隱式提交的數據定義語言(DDL)語句。因此,這是不能做到的。

我試着用DROP裏面的DROP調用一個PROCEDURE來顯式地處理提交,但是也不可能。

任何建議鏡像這2個表?


UPDATE:使用Bill Karwinsuggestion,我添加了一個origin字段每個表與相應的默認谷AB。於是,我改變(刪除並重新創建)如下觸發器:在

觸發:B中

... 
BEGIN 
IF NEW.`origin`='A' THEN 
    INSERT INTO `B` 
     SET `id` = NEW.`id`, `name` = NEW.`name`, `origin` = NEW.`origin`; 
    END IF; 
END 

觸發:

... 
BEGIN 
IF NEW.`origin`='B' THEN 
    INSERT INTO `A` 
     SET `id` = NEW.`id`, `name` = NEW.`name`, `origin` = NEW.`origin`; 
    END IF; 
END 

回答

2

你需要一些方法來避免創建一個週期。

我建議在兩個表中添加一列origin。在表A中,製作DEFAULT 'A'。在表B中,製作DEFAULT 'B'

當插入到應用程序中的任何一個表中時,總是省略origin列,使其成爲默認值。

在這兩個觸發器中,只有當NEW.origin等於各自表的默認值時,纔會複製到其他表。


回覆您的評論和新的錯誤:

對不起,我忘了提及的是,在觸發插入到另一個表時,還必須複製的NEW.origin值。只要在您的應用程序中執行原始插入操作時,您是否省略了origin

觸發在答:

... 
BEGIN 
IF NEW.`origin`='A' THEN 
    INSERT INTO `B` 
     SET `id` = NEW.`id`, `name` = NEW.`name`, `origin` = NEW.`origin`; 
    END IF; 
END 

觸發在B:

... 
BEGIN 
IF NEW.`origin`='B' THEN 
    INSERT INTO `A` 
     SET `id` = NEW.`id`, `name` = NEW.`name`, `origin` = NEW.`origin`; 
    END IF; 
END 

我創建這些觸發器,然後進行測試:

mysql> insert into A set name = 'bill'; 
Query OK, 1 row affected (0.00 sec) 

mysql> insert into B set name = 'john'; 
Query OK, 1 row affected (0.01 sec) 

mysql> select * from A; 
+----+------+--------+ 
| id | name | origin | 
+----+------+--------+ 
| 1 | bill | A  | 
| 2 | john | B  | 
+----+------+--------+ 
2 rows in set (0.00 sec) 

mysql> select * from B; 
+----+------+--------+ 
| id | name | origin | 
+----+------+--------+ 
| 1 | bill | A  | 
| 2 | john | B  | 
+----+------+--------+ 
+0

非常感謝您的專用時間!我測試了它,並且效果很棒! – 2014-10-29 19:15:05