2009-01-02 49 views
3

我一直在閱讀關於create trigger page 的MySql 5.0評論流,我想問問社區如果建議是好的&他們是否仍然適用於5.1。我注意到今天使用觸發器玩的是,使用AFTER UPDATE更新舊錶中的字段是不可能的。BEFORE或AFTER維護審計日誌的觸發器

  1. 請小心BEFORE觸發器。可能會發生約束,特別是如果您使用的InnoDB引擎,插入將失敗,但來自BEFORE觸發器的操作將成功。
  2. 使用BEFORE觸發器主要用於約束或規則,而不是事務,調整NEW。*列應該沒問題。
  3. 堅持AFTER觸發器爲大多數其他操作,如插入歷史表或更新非規範化。

回答

13

是的。 AFAIK,MySQL 5.1沒有對觸發器的工作語義做任何改變。 MySQL試圖支持觸發語義的ANSI/ISO SQL規範。

你能想象有運行作爲行寫入到數據庫的一系列操作:

  1. 運行之前觸發
  2. 評估約束,強制NOT NULL,適用DEFAULT
  3. 寫的行到數據庫
  4. 更新索引
  5. 運行AFTER觸發器

一旦您到達AFTER觸發器,更改行中的值就太遲了。在某些數據庫中,您可以設置NEW.somecolumn = 1234,但隨着AFTER觸發器完成,此更改將被靜默丟棄。在其他數據庫中,通過在定義觸發器或運行觸發器時爲您提供錯誤,可幫助您瞭解自己的錯誤。

AFTER觸發器最適合用於由於行的INSERT/UPDATE引起的額外操作,例如您提到的審計日誌記錄。首先,MySQL只允許每個表的每個動作觸發一次觸發器,所以如果您還使用BEFORE觸發器更改值並強制實施業務規則,那麼現在至少可以將其他操作保留在單獨的觸發器中。這使得更新一個或另一個更容易。

另一個考慮是你應該只在之後做額外的動作你知道該行已經保存成功。例如。在BEFORE觸發器中記錄更改並不正確,然後由於NOT NULL約束而導致更改中止。

對於需要刪除其他表中的相關行的DELETE操作,您可能仍需要在BEFORE觸發器中執行此操作。

+0

感謝您的廣泛答覆。我決定手動更新dateChanged列,而不是依賴觸發器。 – ashitaka 2009-01-05 02:51:46