2011-07-07 152 views
2

我們正在兩個系統之間進行遷移,並且需要有一個始終保持同步的數據庫表中的兩個字段。下面是表的結構:MySQL觸發器更新新行

CREATE TABLE `example` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `object_id` int(11) NOT NULL DEFAULT '0', 
    `value` varchar(200) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `object_id` (`object_id`) 
); 

系統的一個插入新行,我們需要有OBJECT_ID了ID每次。由於id列是一個auto_increment列,所以在插入之前它的值爲NULL,並且由於'在插入'之後MySQL的限制,我們不能使用'插入前',因爲id列是auto_increment列,我不能執行以下操作:

CREATE TRIGGER insert_example 
    AFTER INSERT ON example 
    FOR EACH ROW 
    SET NEW.object_id = NEW.id; 

我無法更新任何系統的代碼,所以我需要一種方法在數據庫端完成此操作。兩個系統都將插入新的行。我怎樣才能做到這一點?

回答

5

使用插入之前這觸發了觸發器應該做的工作

CREATE TRIGGER insert_example 
    BEFORE INSERT ON example 
    FOR EACH ROW 
    SET NEW.object_id = NEW.id; 

編輯:

由於OP指出NEW.id不適用於自動增量;一個可以使用下面的觸發器(在風險自負):

CREATE TRIGGER insert_example 
     BEFORE INSERT ON example 
     FOR EACH ROW 
     SET NEW.object_id = (
      SELECT AUTO_INCREMENT 
      FROM information_schema.TABLES 
      WHERE TABLE_SCHEMA = DATABASE() 
      AND TABLE_NAME = 'example' 
    ); 

但我寧願重新思考這個有些奇怪的要求 - 爲什麼你需要的PK值的兩倍的表?

+0

您可以從之前的NEW.id在插入產生這樣的插入之前,它的價值不是用0 –

+0

右邊...我編輯我的答案 – wonk0

0

是否有任何理由你不能使用BEFORE INSERT觸發器?

我一直都看到AFTER INSERT觸發器作爲操縱其他表的方法,而不是觸發器在其上執行的表。

經驗法則,操縱表觸發器是在= BEFORE INSERT運行,操縱其他表AFTER INSERT :)

+0

以前不能使用,因爲插入時生成NEW.id,所以在插入之前它的值爲0. –

+0

啊,有道理。忽略了它是auto_increment字段的事實,對不起。然後覺得你有點卡在這裏。無論如何,您可以修復數據庫設計並擺脫冗餘數據嗎? (如正常化一點) – JustDanyul

+0

沒有。不幸的是,這些系統之間的遷移過程中我們必須忍受這些。一個系統使用ID字段,另一個系統使用OBJECT_ID字段。兩者都需要現在和同步。 –

-1

我認爲你的觸發器永遠不會創建,因爲你不能在AFTER INSERT觸發器中引用NEW.column_name。

嘗試在BEFORE INSERT觸發器這樣做(請忽略此FIX因爲它不會工作):

CREATE TRIGGER `insert_example` BEFORE INSERT ON `t` 
FOR EACH ROW 
SET NEW.`object_id` = NEW.`id`; 

請更改表和列名,按您的架構。

希望這會有所幫助。

+0

不能使用之前,因爲NEW.id是在刀片上產生如此前它的值插入0 –

+0

這是正確的@Russell C,我想我在這裏混了兩件事情。不管怎麼說,謝謝指正了 – Abhay