1. 程式人生 > 資料庫 >mysql觸發器之建立多個觸發器操作例項分析

mysql觸發器之建立多個觸發器操作例項分析

本文例項講述了mysql觸發器之建立多個觸發器操作。分享給大家供大家參考,具體如下:

這次記錄的內容mysql 版本必須得是5.7.2+的哈,之前的會不好使的。廢話不多說,咱們開始正文哈。

在mysql 5.7.2+版本之前,我們只能為表中的事件建立一個觸發器,例如,只能為BEFORE UPDATE或AFTER UPDATE事件建立一個觸發器。 mysql 5.7.2+版本解決了這樣限制,並允許我們為表中的相同事件和動作時間建立多個觸發器。當事件發生時,觸發器將依次啟用。我們來參考建立第一個觸發器中的語法。如果表中有相同事件有多個觸發器,mysql 將按照建立的順序呼叫觸發器。要更改觸發器的順序,需要在FOR EACH ROW子句之後指定FOLLOWS或PRECEDES。我們來看下這兩個詞的說明:

  • FOLLOWS選項允許新觸發器在現有觸發器之後啟用。
  • PRECEDES選項允許新觸發器在現有觸發器之前啟用。

完事來看下使用顯式順序建立新的附加觸發器的語法:

DELIMITER $$
CREATE TRIGGER trigger_name
[BEFORE|AFTER] [INSERT|UPDATE|DELETE] ON table_name
FOR EACH ROW [FOLLOWS|PRECEDES] existing_trigger_name
BEGIN
…
END$$
DELIMITER ;

然後,我們來看一個在表中的同一個事件和動作上,建立多個觸發器的例子。我們來基於products表進行演示,首先來建立一個新的price_logs表,完事呢,每當更改產品的價格(MSRP列)時,要將舊的價格記錄在一個名為price_logs的表中,先來看想sql:

CREATE TABLE price_logs (
 id INT(11) NOT NULL AUTO_INCREMENT,product_code VARCHAR(15) NOT NULL,price DOUBLE NOT NULL,updated_at TIMESTAMP NOT NULL DEFAULT 
       CURRENT_TIMESTAMP 
       ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (id),KEY product_code (product_code),CONSTRAINT price_logs_ibfk_1 FOREIGN KEY (product_code) 
 REFERENCES products (productCode) 
 ON DELETE CASCADE 
 ON UPDATE CASCADE
);

完事,當表的BEFORE UPDATE事件發生時,建立一個新的觸發器。觸發器名稱為before_products_update,具體實現如下所示:

DELIMITER $$
CREATE TRIGGER before_products_update 
  BEFORE UPDATE ON products 
  FOR EACH ROW 
BEGIN
   INSERT INTO price_logs(product_code,price)
   VALUES(old.productCode,old.msrp);
END$$
DELIMITER ;

然後,當我們更改產品的價格,並使用以下update語句,最後查詢price_logs表:

UPDATE products
SET msrp = 95.1
WHERE productCode = 'S10_1678';
-- 查詢結果價格記錄
SELECT * FROM price_logs;

上面查詢語句執行後,得到以下結果:

+----+--------------+-------+---------------------+
| id | product_code | price | updated_at     |
+----+--------------+-------+---------------------+
| 1 | S10_1678   | 95.7 | 2017-08-03 02:46:42 |
+----+--------------+-------+---------------------+
1 row in set

可以看到結果中,它按我們預期那樣工作了。

完事我們再來假設不僅要看到舊的價格,改變的時候,還要記錄是誰修改了它。要實現這個,我們可以向price_logs表新增其他列,但是,為了實現多個觸發器的演示,我們將建立一個新表來儲存進行更改的使用者的資料。這個新表的名稱為user_change_logs,結構如下:

CREATE TABLE user_change_logs (
 id int(11) NOT NULL AUTO_INCREMENT,product_code varchar(15) DEFAULT NULL,updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP 
 ON UPDATE CURRENT_TIMESTAMP,updated_by varchar(30) NOT NULL,CONSTRAINT user_change_logs_ibfk_1 FOREIGN KEY (product_code) 
 REFERENCES products (productCode) 
 ON DELETE CASCADE ON UPDATE CASCADE
);

現在,我們建立一個在products表上的BEFORE UPDATE事件上啟用的第二個觸發器。 此觸發器將更改的使用者資訊更新到user_change_logs表。 它在before_products_update觸發後被啟用:

DELIMITER $$
CREATE TRIGGER before_products_update_2 
  BEFORE UPDATE ON products 
  FOR EACH ROW FOLLOWS before_products_update
BEGIN
  INSERT INTO user_change_logs(product_code,updated_by)
  VALUES(old.productCode,user());
END$$
DELIMITER ;

然後我們來使用update語句更新指定產品的價格:

UPDATE products
SET msrp = 95.3
WHERE productCode = 'S10_1678';

再來分別從price_logs和user_change_logs表查詢資料:

mysql> SELECT * FROM price_logs;
+----+--------------+-------+---------------------+
| id | product_code | price | updated_at     |
+----+--------------+-------+---------------------+
| 1 | S10_1678   | 95.7 | 2017-08-03 02:46:42 |
| 2 | S10_1678   | 95.1 | 2017-08-03 02:47:21 |
+----+--------------+-------+---------------------+
2 rows in set
mysql> SELECT * FROM user_change_logs;
+----+--------------+---------------------+----------------+
| id | product_code | updated_at     | updated_by   |
+----+--------------+---------------------+----------------+
| 1 | S10_1678   | 2017-08-03 02:47:21 | root@localhost |
+----+--------------+---------------------+----------------+
1 row in set

如上所見,兩個觸發器按照預期的順序啟用執行相關操作了。完事我們來在information_schema資料庫的triggers表中的action_order列,看下觸發啟用同一事件和操作的順序:

mysql> SELECT 
  trigger_name,action_order
FROM
  information_schema.triggers
WHERE
  trigger_schema = 'yiibaidb'
ORDER BY event_object_table,action_timing,event_manipulation;
+--------------------------+--------------+
| trigger_name       | action_order |
+--------------------------+--------------+
| before_employee_update  |      1 |
| before_products_update  |      1 |
| before_products_update_2 |      2 |
+--------------------------+--------------+
3 rows in set

好啦,本次記錄就到這裡了。

更多關於MySQL相關內容感興趣的讀者可檢視本站專題:《MySQL查詢技巧大全》、《MySQL事務操作技巧彙總》、《MySQL儲存過程技巧大全》、《MySQL資料庫鎖相關技巧彙總》及《MySQL常用函式大彙總》

希望本文所述對大家MySQL資料庫計有所幫助。