2013-09-23 52 views
2

我需要在插入時將auto_increment ID值複製到另一列中。 我想我需要一個「插入後」觸發器,因爲否則新ID不知道..?MySQL觸發器:在插入時將auto_increment值複製到另一列

我嘗試這樣做:

IF NEW.content IS NULL THEN 
    SET NEW.content = NEW.id; 
END IF 

但抱怨:

Updating of NEW row is not allowed in after trigger

+0

你的桌子的名字是什麼? –

+0

表名爲'notes' – kvdmolen

+0

CREATE TRIGGER insert_example 插入前示例 FOR EACH ROW SET NEW.object_id = NEW.id;嘗試這個。 –

回答

0

是的,這是不可能的觸發器。你可以做的最好的是你用CALL some_procedure(values...)代替INSERT聲明,並在那裏實現上述邏輯。 (假設您可以在應用程序端更改SQL)。

另一個(但醜陋的)解決方案,以建立一個事件時,定期修復您的記錄,其中content=NULL

0

由於OP指出NEW.id不會自動遞增工作;人們可以使用以下觸發器(使用風險自負)。嘗試這個。

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

同樣,我想到一個帶有NEW.content = LAST_INSERT_ID()+ 1的BEFORE INSERT觸發器,但我認爲這也有風險.. – kvdmolen

+0

是的。你可以選擇你自己。 –

+0

不保證下一個auto_increment值是'LAST_INSERT_ID()+ 1'。看到[INNODB的autoinc_lock_mode](http://dev.mysql.com/doc/refman/5.5/en/innodb-auto-increment-handling.html) –

0

位A bodge的,由可你剛纔說

DELIMITER $$ 
CREATE TRIGGER sometrigger 
AFTER INSERT ON sometable 
BEGIN 
    UPDATE sometable SET content = NEW.id WHERE id = NEW.id; 
END $$ 

更新(下同)表通過一個完整的查詢,而不是試圖用SET。

甚至

DELIMITER $$ 
CREATE TRIGGER sometrigger 
AFTER INSERT ON sometable 
BEGIN 
    UPDATE sometable SET content = id WHERE content is null; 
END $$ 

(這是有點類似事件的Allita的建議)

+0

它不會在MySQL中工作。您不能在定義了該觸發器的表上的觸發器中執行任何DML語句。 – peterm

+0

後者給出了另一個錯誤:「無法更新存儲函數/觸發器中的表'註釋',因爲它已經被調用此存儲函數/觸發器的語句使用。」 – kvdmolen

+0

對不起。我承認沒有嘗試過。我用觸發器插入(另一個)新行,但沒有嘗試更新只是假定它會工作。我不能低估自己的答案! – barryhunter

0

如果你真的需要這種行爲出於某種原因,你可以通過使用一個單獨的表實現它用於測序和BEFORE INSERT觸發器

首先您需要一個簡單的表格用於測序目的,可能看起來像

CREATE TABLE table1_seq 
(
    id int not null auto_increment primary key 
); 

那麼你的事實表的模式可能看起來像

CREATE TABLE table1 
(
    id int not null default 0 primary key, 
    content int 
); 

現在觸發

DELIMITER $$ 
CREATE TRIGGER tg_ai_table1 
BEFORE INSERT ON table1 
FOR EACH ROW 
BEGIN 
    INSERT INTO table1_seq() VALUES(); 
    SET NEW.id = LAST_INSERT_ID(), NEW.content = COALESCE(NEW.content, NEW.id); 
END$$ 
DELIMITER ; 

現在,如果你插入table1

INSERT INTO table1() VALUES (NULL),(-1); 

你必須

 
| ID | CONTENT | 
|----|---------| 
| 1 |  1 | 
| 2 |  -1 | 

這裏是SQLFiddle演示

+0

@kvdmolen有幫助嗎?你的問題需要更多幫助嗎? – peterm

+0

答案是:不可能使用觸發器。我更喜歡更簡單的解決方法(請參閱第一個問題中的註釋),否則我將不得不在應用程序層中構建它。謝謝你的幫助! – kvdmolen

2

在此代碼

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

我做了這樣的事情

SET NEW.content = (SELECT CONCAT('ID',LPAD(AUTO_INCREMENT, number,'0')) 
FROM information_schema.TABLES 
WHERE TABLE_SCHEMA = DATABASE() 
AND TABLE_NAME = 'notes'); 

的情況下,你使用UNSIGNED_ZEROFILL的id字段和...您可能需要自定義類型的「公開」ID ...

相關問題