名稱 描述 BEFORE 表示在具體的語句執行之前就開始執行觸發器的內容 AFTER 表示在具體的語句執行之后才開始執行觸發器的內容 {INSERT|DELETE|UPDATE}表示具體的語句,MySQL中目前只支持對INSERT、DELETE、UPDATE這三種類型的語句設置觸發器。
FOR EACH ROW BEGIN ... END表示對具體語句影響的每一條記錄都執行我們自定義的觸發器內容:
對于INSERT語句來說,FOR EACH ROW影響的記錄就是我們準備插入的那些新記錄。 對于DELETE語句和UPDATE語句來說,FOR EACH ROW影響的記錄就是符合WHERE條件的那些記錄(如果語句中沒有WHERE條件,那就是代表全部的記錄)。 小貼士: 如果觸發器內容只包含一條語句,那也可以省略BEGN、END這兩個詞兒。
mysql> delimiter $ mysql> CREATE TRIGGER bi_t1 -> BEFORE INSERT ON t1 -> FOR EACH ROW -> BEGIN -> IF NEW.m1 < 1 THEN -> SET NEW.m1 = 1; -> ELSEIF NEW.m1 > 10 THEN -> SET NEW.m1 = 10; -> END IF; -> END $ Query OK, 0 rows affected (0.02 sec)
觸發器使用注意事項 觸發器內容中不能有輸出結果集的語句。比方說: mysql> delimiter $ mysql> CREATE TRIGGER ai_t1 -> AFTER INSERT ON t1 -> FOR EACH ROW -> BEGIN -> SELECT NEW.m1, NEW.n1; -> END $ ERROR 1415 (0A000): Not allowed to return a result set from a trigger mysql> 顯示的ERROR的意思就是不允許在觸發器內容中返回結果集! 觸發器內容中NEW代表記錄的列的值可以被更改,OLD代表記錄的列的值無法更改。NEW代表新插入或著即將修改后的記錄,修改它的列的值將影響INSERT和UPDATE語句執行后的結果,而OLD代表修改或刪除之前的值,我們無法修改它。比方說如果我們非要這么寫那就會報錯的: mysql> delimiter $ mysql> CREATE TRIGGER bu_t1 -> BEFORE UPDATE ON t1 -> FOR EACH ROW -> BEGIN -> SET OLD.m1 = 1; -> END $ ERROR 1362 (HY000): Updating of OLD row is not allowed in trigger mysql> 可以看到提示的錯誤中顯示在觸發器中OLD代表的記錄是不可被更改的。 在BEFORE觸發器中,我們可以使用SET NEW.列名 = 某個值的形式來更改待插入記錄或者待更新記錄的某個列的值,但是這種操作不能在AFTER觸發器中使用,因為在執行AFTER觸發器的內容時記錄已經被插入完成或者更新完成了。比方說如果我們非要這么寫那就會報錯的: mysql> delimiter $ mysql> CREATE TRIGGER ai_t1 -> AFTER INSERT ON t1 -> FOR EACH ROW -> BEGIN -> SET NEW.m1 = 1; -> END $ ERROR 1362 (HY000): Updating of NEW row is not allowed in after trigger mysql> 可以看到提示的錯誤中顯示在AFTER觸發器中是不允許更改NEW代表的記錄的。 如果我們的BEFORE觸發器內容執行過程中遇到了錯誤,那這個觸發器對應的具體語句將無法執行;如果具體的操作語句執行過程中遇到了錯誤,那與它對應的AFTER觸發器的內容將無法執行。 小貼士: 對于支持事務的表,不論是執行觸發器內容還是具體操作語句過程中出現了錯誤,會把這個過程中所有的語句都回滾。當然,作為小白的我們并不知道啥是個事務,啥是個回滾,這些進階內容都在《MySQL是怎樣運行的:從根兒上理解MySQL》中呢~ 事件 有時候我們想讓MySQL服務器在某個時間點或者每隔一段時間自動地執行一些語句,這時候就需要去創建一個事件。
創建事件 創建事件的語法如下:
CREATE EVENT 事件名 ON SCHEDULE { AT 某個確定的時間點| EVERY 期望的時間間隔 [STARTS datetime][END datetime] } DO BEGIN 具體的語句 END 事件支持兩種類型的自動執行方式:
在某個確定的時間點執行。比方說: CREATE EVENT insert_t1_event ON SCHEDULE AT '2019-09-04 15:48:54' DO BEGIN INSERT INTO t1(m1, n1) VALUES(6, 'f'); END 我們在這個事件中指定了執行時間是'2019-09-04 15:48:54',除了直接填某個時間常量,我們也可以填寫一些表達式: CREATE EVENT insert_t1 ON SCHEDULE AT DATE_ADD(NOW(), INTERVAL 2 DAY) DO BEGIN INSERT INTO t1(m1, n1) VALUES(6, 'f'); END 其中的DATE_ADD(NOW(), INTERVAL 2 DAY)表示該事件將在當前時間的兩天后執行。 每隔一段時間執行一次。比方說: CREATE EVENT insert_t1 ON SCHEDULE EVERY 1 HOUR DO BEGIN INSERT INTO t1(m1, n1) VALUES(6, 'f'); END 其中的EVERY 1 HOUR表示該事件將每隔1個小時執行一次。默認情況下,采用這種每隔一段時間執行一次的方式將從創建事件的事件開始,無限制的執行下去。我們也可以指定該事件開始執行時間和截止時間: CREATE EVENT insert_t1 ON SCHEDULE EVERY 1 HOUR STARTS '2019-09-04 15:48:54' ENDS '2019-09-16 15:48:54' DO BEGIN INSERT INTO t1(m1, n1) VALUES(6, 'f'); END 如上所示,該事件將從'2019-09-04 15:48:54'開始直到'2019-09-16 15:48:54'為止,中間每隔1個小時執行一次。 小貼士: 表示事件間隔的單位除了HOUR,還可以用YEAR、QUARTER、MONTH、DAY、HOUR、 MINUTE、WEEK、SECOND、YEAR_MONTH、DAY_HOUR、DAY_MINUTE、DAY_SECOND、HOUR_MINUTE、HOUR_SECOND、MINUTE_SECOND這些單位,根據具體需求選用我們需要的時間間隔單位。 在創建好事件之后我們就不用管了,到了指定時間,MySQL服務器會幫我們自動執行的。