MySQL 学习笔记(8)— 触发器
1. 觸發器概念
觸發器是 MySQL 響應以下任意語句而自動執行的一條 MySQL 語句(或位于BEGIN 和 END 語句之間的一組語句)
INSERTUPDATEDELETE
其他 MySQL 語句不支持觸發器。
保持每個數據庫的觸發器名唯一
2. 創建觸發器
創建觸發器的基本語法如下:
CREATE TRIGGER trigger_name
{BEFORE | AFTER | INSTEAD OF} triggering_event ON table_name
[FOR EACH ROW] | [FOR EACH STATEMENT]
trigger_body;
其中:
CREATE TRIGGER表示創建一個觸發器,trigger_name是觸發的名稱;BEFORE、AFTER、分別表示觸發的時機,INSTEAD OF表示替代觸發器;triggering_event定義了觸發事件,例如INSERT、UPDATE、DELETE等;table_name表示與觸發事件相關的表;FOR EACH ROW表示行級觸發器,FOR EACH STATEMENT表示語句級觸發器;trigger_body定義了觸發器執行的操作,具體的實現與存儲過程或函數類似。
在創建觸發器時,需要給出 4 條信息:
- 唯一的觸發器名;
- 觸發器關聯的表;
- 觸發器應該響應的活動(
DELETE、INSERT或UPDATE); - 觸發器何時執行(處理之前或之后)。
mysql> CREATE TRIGGER new_product
AFTER INSERT ON products
FOR EACH ROW SELECT 'Product added';
1415 - Not allowed to return a result set from a trigger
CREATE TRIGGER 用來創建名為 new_product 的新觸發器。觸發器可在一個操作發生之前或之后執行,這里給出了 AFTER INSERT,所以此觸發器將在 INSERT 語句成功執行后執行。這個觸發器還指定 FOR EACH ROW,因此代碼對每個插入行執行。在這個例子中,文本 Product added 將對每個插入的行顯示一次。
為了測試這個觸發器,使用 INSERT 語句添加一行或多行到 products 中,你將看到對每個成功的插入,顯示 Product added 消息。
mysql> INSERT INTO products
values ('004', '1005', 'HM', 75, 'fashion');
Query OK, 1 row affectedmysql> SELECT 'Product added';
+---------------+
| Product added |
+---------------+
| Product added |
+---------------+
1 row in setmysql>
3. 刪除觸發器
為了刪除一個觸發器,可使用 DROP TRIGGER 語句,如下所示:
mysql> DROP TRIGGER new_productmysql>
4. 觸發器類型
觸發器按每個表每個事件每次地定義,每個表每個事件每次只允許一個觸發器。
因此,每個表最多支持 6 個觸發器(每條 INSERT、UPDATE 和 DELETE 的之前和之后)。單一觸發器不能與多個事件或多個表關聯,所以,如果你需要一個對 INSERT 和 UPDATE 操作執行的觸發器,則應該定義兩個觸發器。
觸發器失敗
如果BEFORE觸發器失敗,則MySQL將不執行請求的操作。此外,如果BEFORE觸發器或語句本身失敗,MySQL將不執行AFTER觸發器(如果有的話)。
5. INSERT 觸發器
INSERT 觸發器在 INSERT 語句執行之前或之后執行。需要知道以下幾點:
- 在
INSERT觸發器代碼內,可引用一個名為NEW的虛擬表,訪問被插入的行; - 在
BEFORE INSERT觸發器中,NEW中的值也可以被更新(允許更改被插入的值); - 對于
AUTO_INCREMENT列,NEW在INSERT執行之前包含0,在INSERT執行之后包含新的自動生成值。
mysql> CREATE TRIGGER neworder
AFTER INSERT ON orders
FOR EACH ROW SELECT NEW.order_num into @order_num_result;
Query OK, 0 rows affectedmysql>
此代碼創建一個名為 neworder 的觸發器,它按照 AFTER INSERT ON orders執行。
在插入一個新訂單到 orders 表時,MySQL 生成一個新訂單號并保存到 order_num 中。觸發器從 NEW. order_num 取得這個值并返回它。此觸發器必須按照 AFTER INSERT 執行,因為在 BEFORE
INSERT 語句執行之前,新 order_num 還沒有生成。對于 orders 的每次插入使用這個觸發器將總是返回新的訂單號。
mysql> INSERT INTO orders (order_date, cust_id)
VALUES (now(), 10003);
Query OK, 1 row affectedmysql> SELECT @order_num_result;
+-------------------+
| @order_num_result |
+-------------------+
| 20011 |
+-------------------+
1 row in setmysql>
6. DELETE 觸發器
DELETE 觸發器在 DELETE 語句執行之前或之后執行。需要知道以下兩點:
- 在
DELETE觸發器代碼內,你可以引用一個名為OLD的虛擬表,訪問被刪除的行; OLD中的值全都是只讀的,不能更新;
mysql> CREATE TRIGGER deleteorder
AFTER DELETE ON orders FOR EACH ROW
BEGININSERT INTO archive_orders(order_date, cust_id)VALUES(OLD.order_date, OLD.cust_id)
END
在任意訂單被刪除前將執行此觸發器。它使用一條 INSERT 語句將 OLD 中的值(要被刪除的訂單)保存到一個名為 archive_orders 的存檔表中(為實際使用這個例子,你需要用與 orders 相同的列創建一個名為 archive_orders 的表)。
多語句觸發器 正如所見,觸發器 deleteorder 使用 BEGIN 和 END 語句標記觸發器體。這在此例子中并不是必需的,不過也沒有害處。使用 BEGIN END 塊的好處是觸發器能容納多條 SQL 語句(在 BEGIN END 塊中一條挨著一條)。
7. UPDATE 觸發器
UPDATE 觸發器在 UPDATE 語句執行之前或之后執行。需要知道以下幾點:
- 在
UPDATE觸發器代碼中,你可以引用一個名為OLD的虛擬表訪問以前(UPDATE語句前)的值,引用一個名為NEW的虛擬表訪問新更新的值; - 在
BEFORE UPDATE觸發器中,NEW中的值可能也被更新(允許更改將要用于UPDATE語句中的值); OLD中的值全都是只讀的,不能更新。
mysql> CREATE TRIGGER updatevendor BEFORE UPDATE ON vendors
FOR EACH ROW SET NEW.vend_state=Upper(NEW.vend_state);
Query OK, 0 rows affectedmysql> update vendors set vend_state="china" where vend_id=1006;
Query OK, 1 row affected
Rows matched: 1 Changed: 1 Warnings: 0mysql>
每次更新一個行時,NEW.vend_state 中的值(將用來更新表行的值)都 Upper(NEW.vend_state) 替換。
8. 觸發器總結
只有表支持觸發器,視圖和臨時表均不支持觸發器。
總結
以上是生活随笔為你收集整理的MySQL 学习笔记(8)— 触发器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 去泸沽湖有什么交通方式,下飞机后怎么去泸
- 下一篇: 求一个男孩带木字好听的名字。