2012-02-13 83 views
5

我有一個插入觸發器,它從表A中的行獲取一組列值,並將其中的一部分插入到表B中並保留在表C中。我需要此操作爲事務,其中如果在數據插入到表B而不是C時存在一些錯誤,則整個插入操作應該被回滾。我可以在MySQL觸發器中使用像事務這樣的事務

我學的是手動和它在最後this頁的說,交易是不是在觸發器

允許有沒有辦法達到我想要在MySQL。

+1

您可以在存儲過程中執行相同的操作。 – 2012-02-13 04:32:13

+0

我需要在表A中插入新記錄時啓動此操作,這就是爲什麼我使用觸發器的原因。這可以通過存儲過程來完成嗎? – Abhishek 2012-02-13 04:36:23

+0

您可以在存儲過程中運行多個語句。 – 2012-02-13 04:45:11

回答

4

是的,你可以,但你怎麼做取決於你的版本。

首先,觸發器本身是事務性的;在你的情況下,你有一個插入觸發器來執行另外兩個插入。如果其中一個失敗,你會得到你想要的效果。

請看下面的例子:

CREATE TABLE a (colA INT); 
CREATE TABLE b (colB INT); 
CREATE TABLE c (colC INT); 
delimiter : 
CREATE TRIGGER testtrig BEFORE INSERT ON a 
    FOR EACH ROW BEGIN 
    INSERT INTO b(colB) VALUES(NEW.colA); 
    INSERT INTO c(banana) VALUES (NEW.colA); -- note the faulty column name 
END;: 
delimiter ; 

現在,當我運行失敗的插入,這種情況發生:

mysql> INSERT INTO a VALUES (5); 
ERROR 1054 (42S22): Unknown column 'banana' in 'field list' 
mysql> SELECT * FROM a; 
Empty set (0.00 sec) 

這符合你的期望的結果。

更一般地,如果你有,你可以使用試圖插入之前驗證您的數據的邏輯,你可以失敗觸發以不同的方式:

  • 在MySQL 5.5中,你可以使用SIGNAL機制,以提高來自觸發器的錯誤,從而導致整個插入失敗。
  • 在MySQL 5.5之前,您可以生成故意的錯誤以使觸發器失敗。

我猜你正在使用5.0從你的問題的鏈接,所以如果你需要,你可以執行故意的錯誤,例如故意插入到一個無效的列,使觸發失敗。但是,您在問題中描述的情況已經以交易方式處理,正如我在答案開始處所述。

0

默認情況下,您會得到您要求的內容 - 觸發器中的任何錯誤都會導致語句失敗。因此,如果在語句中有一個事務,則會在該語句之前將數據回滾。如果沒有交易,那麼你沒有。

這可能是爲什麼在觸發器中不允許創建或結束事務。

因此不需要存儲過程。實際上,如果您嘗試創建事務,則從觸發器調用的存儲過程可能會導致錯誤。

但是,在執行導致觸發器的操作之前,請隨時使用存儲過程來啓動事務。