MySQL 学习笔记(8)— 触发器
1. 觸發(fā)器概念
觸發(fā)器是 MySQL 響應(yīng)以下任意語(yǔ)句而自動(dòng)執(zhí)行的一條 MySQL 語(yǔ)句(或位于BEGIN 和 END 語(yǔ)句之間的一組語(yǔ)句)
INSERTUPDATEDELETE
其他 MySQL 語(yǔ)句不支持觸發(fā)器。
保持每個(gè)數(shù)據(jù)庫(kù)的觸發(fā)器名唯一
2. 創(chuàng)建觸發(fā)器
創(chuàng)建觸發(fā)器的基本語(yǔ)法如下:
CREATE TRIGGER trigger_name
{BEFORE | AFTER | INSTEAD OF} triggering_event ON table_name
[FOR EACH ROW] | [FOR EACH STATEMENT]
trigger_body;
其中:
CREATE TRIGGER表示創(chuàng)建一個(gè)觸發(fā)器,trigger_name是觸發(fā)的名稱;BEFORE、AFTER、分別表示觸發(fā)的時(shí)機(jī),INSTEAD OF表示替代觸發(fā)器;triggering_event定義了觸發(fā)事件,例如INSERT、UPDATE、DELETE等;table_name表示與觸發(fā)事件相關(guān)的表;FOR EACH ROW表示行級(jí)觸發(fā)器,FOR EACH STATEMENT表示語(yǔ)句級(jí)觸發(fā)器;trigger_body定義了觸發(fā)器執(zhí)行的操作,具體的實(shí)現(xiàn)與存儲(chǔ)過(guò)程或函數(shù)類似。
在創(chuàng)建觸發(fā)器時(shí),需要給出 4 條信息:
- 唯一的觸發(fā)器名;
- 觸發(fā)器關(guān)聯(lián)的表;
- 觸發(fā)器應(yīng)該響應(yīng)的活動(dòng)(
DELETE、INSERT或UPDATE); - 觸發(fā)器何時(shí)執(zhí)行(處理之前或之后)。
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 用來(lái)創(chuàng)建名為 new_product 的新觸發(fā)器。觸發(fā)器可在一個(gè)操作發(fā)生之前或之后執(zhí)行,這里給出了 AFTER INSERT,所以此觸發(fā)器將在 INSERT 語(yǔ)句成功執(zhí)行后執(zhí)行。這個(gè)觸發(fā)器還指定 FOR EACH ROW,因此代碼對(duì)每個(gè)插入行執(zhí)行。在這個(gè)例子中,文本 Product added 將對(duì)每個(gè)插入的行顯示一次。
為了測(cè)試這個(gè)觸發(fā)器,使用 INSERT 語(yǔ)句添加一行或多行到 products 中,你將看到對(duì)每個(gè)成功的插入,顯示 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. 刪除觸發(fā)器
為了刪除一個(gè)觸發(fā)器,可使用 DROP TRIGGER 語(yǔ)句,如下所示:
mysql> DROP TRIGGER new_productmysql>
4. 觸發(fā)器類型
觸發(fā)器按每個(gè)表每個(gè)事件每次地定義,每個(gè)表每個(gè)事件每次只允許一個(gè)觸發(fā)器。
因此,每個(gè)表最多支持 6 個(gè)觸發(fā)器(每條 INSERT、UPDATE 和 DELETE 的之前和之后)。單一觸發(fā)器不能與多個(gè)事件或多個(gè)表關(guān)聯(lián),所以,如果你需要一個(gè)對(duì) INSERT 和 UPDATE 操作執(zhí)行的觸發(fā)器,則應(yīng)該定義兩個(gè)觸發(fā)器。
觸發(fā)器失敗
如果BEFORE觸發(fā)器失敗,則MySQL將不執(zhí)行請(qǐng)求的操作。此外,如果BEFORE觸發(fā)器或語(yǔ)句本身失敗,MySQL將不執(zhí)行AFTER觸發(fā)器(如果有的話)。
5. INSERT 觸發(fā)器
INSERT 觸發(fā)器在 INSERT 語(yǔ)句執(zhí)行之前或之后執(zhí)行。需要知道以下幾點(diǎn):
- 在
INSERT觸發(fā)器代碼內(nèi),可引用一個(gè)名為NEW的虛擬表,訪問(wèn)被插入的行; - 在
BEFORE INSERT觸發(fā)器中,NEW中的值也可以被更新(允許更改被插入的值); - 對(duì)于
AUTO_INCREMENT列,NEW在INSERT執(zhí)行之前包含0,在INSERT執(zhí)行之后包含新的自動(dòng)生成值。
mysql> CREATE TRIGGER neworder
AFTER INSERT ON orders
FOR EACH ROW SELECT NEW.order_num into @order_num_result;
Query OK, 0 rows affectedmysql>
此代碼創(chuàng)建一個(gè)名為 neworder 的觸發(fā)器,它按照 AFTER INSERT ON orders執(zhí)行。
在插入一個(gè)新訂單到 orders 表時(shí),MySQL 生成一個(gè)新訂單號(hào)并保存到 order_num 中。觸發(fā)器從 NEW. order_num 取得這個(gè)值并返回它。此觸發(fā)器必須按照 AFTER INSERT 執(zhí)行,因?yàn)樵?BEFORE
INSERT 語(yǔ)句執(zhí)行之前,新 order_num 還沒(méi)有生成。對(duì)于 orders 的每次插入使用這個(gè)觸發(fā)器將總是返回新的訂單號(hào)。
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 觸發(fā)器
DELETE 觸發(fā)器在 DELETE 語(yǔ)句執(zhí)行之前或之后執(zhí)行。需要知道以下兩點(diǎn):
- 在
DELETE觸發(fā)器代碼內(nèi),你可以引用一個(gè)名為OLD的虛擬表,訪問(wèn)被刪除的行; 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
在任意訂單被刪除前將執(zhí)行此觸發(fā)器。它使用一條 INSERT 語(yǔ)句將 OLD 中的值(要被刪除的訂單)保存到一個(gè)名為 archive_orders 的存檔表中(為實(shí)際使用這個(gè)例子,你需要用與 orders 相同的列創(chuàng)建一個(gè)名為 archive_orders 的表)。
多語(yǔ)句觸發(fā)器 正如所見(jiàn),觸發(fā)器 deleteorder 使用 BEGIN 和 END 語(yǔ)句標(biāo)記觸發(fā)器體。這在此例子中并不是必需的,不過(guò)也沒(méi)有害處。使用 BEGIN END 塊的好處是觸發(fā)器能容納多條 SQL 語(yǔ)句(在 BEGIN END 塊中一條挨著一條)。
7. UPDATE 觸發(fā)器
UPDATE 觸發(fā)器在 UPDATE 語(yǔ)句執(zhí)行之前或之后執(zhí)行。需要知道以下幾點(diǎn):
- 在
UPDATE觸發(fā)器代碼中,你可以引用一個(gè)名為OLD的虛擬表訪問(wèn)以前(UPDATE語(yǔ)句前)的值,引用一個(gè)名為NEW的虛擬表訪問(wèn)新更新的值; - 在
BEFORE UPDATE觸發(fā)器中,NEW中的值可能也被更新(允許更改將要用于UPDATE語(yǔ)句中的值); 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>
每次更新一個(gè)行時(shí),NEW.vend_state 中的值(將用來(lái)更新表行的值)都 Upper(NEW.vend_state) 替換。
8. 觸發(fā)器總結(jié)
只有表支持觸發(fā)器,視圖和臨時(shí)表均不支持觸發(fā)器。
總結(jié)
以上是生活随笔為你收集整理的MySQL 学习笔记(8)— 触发器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 去泸沽湖有什么交通方式,下飞机后怎么去泸
- 下一篇: MySQL 学习笔记(9)— 事务控制语