什麼是觸發器
就是trigger(扳機), 一碰就動, 一觸即發, 就叫觸發器
跟儲存過程類似, 也是主要用於增, 刪, 改
事先為某張表繫結一段程式碼, 當表中的某些內容發生改變的時候(對錶進行增刪改), 系統就會自動觸發程式碼執行
監聽, 只要...就觸發, 然後執行...
![觸發器.png](https://i.iter01.com/images/84dd5fcf95ece1466f98129d2da77b9d3e30f5c6af1a4c9e97f4295865056c32.png)
為什麼需要觸發器?
有些sql語句, 或者資料庫操作, 在邏輯上是緊密相關, 不可分割的, 需要一起執行
建立觸發器
![建立觸發器.png](https://i.iter01.com/images/39f6be34200854aee595ff089546d3a2bf4feb1b904c9fd545de0286dc7c13ca.png)
我們需要一些測試資料
drop database if exists mail;
create database mail character set utf8;
use mail;
create table goods(
goods_id int primary key,
goods_name varchar(20) not null,
goods_inventory int not null
);
create table orders(
orders_id int primary key,
orders_goods_id int not null,
orders_buy_number int not null,
foreign key(orders_goods_id) references goods(goods_id)
);
insert into goods set goods_id = 1, goods_name = 'television', goods_inventory = 20;
insert into goods set goods_id = 2, goods_name = 'bicyle', goods_inventory = 99;
insert into orders set orders_id = 1, orders_goods_id = 1, orders_buy_number = 2;
insert into orders set orders_id = 2, orders_goods_id = 2, orders_buy_number = 10;
複製程式碼
中文版
drop database if exists 商城資料庫;
create database 商城資料庫 character set utf8;
use 商城資料庫;
create table 商品表(
商品ID int primary key,
商品名稱 varchar(20) not null,
商品庫存 int not null
);
create table 訂單表(
訂單ID int primary key,
訂單裡的商品ID int not null,
訂單裡的商品購買數量 int not null,
foreign key(訂單裡的商品ID) references 商品表(商品ID)
);
insert into 商品表 set 商品ID = 1, 商品名稱 = '電視機', 商品庫存 = 20;
insert into 商品表 set 商品ID = 2, 商品名稱 = '自行車', 商品庫存 = 99;
insert into 訂單表 set 訂單ID = 1, 訂單裡的商品ID = 1, 訂單裡的商品購買數量 = 2;
insert into 訂單表 set 訂單ID = 2, 訂單裡的商品ID = 2, 訂單裡的商品購買數量 = 10;
複製程式碼
![商城資料庫.png](https://i.iter01.com/images/36e891c61e2dffc571c81797f212e0fff7acdc83b5f5729622244e3725e562ea.png)
insert
insert之前(語法)
drop trigger if exists 插入前觸發;
create trigger 插入前觸發 before insert on teacher for each row
-- sql語句, 不能是select
begin
end;
複製程式碼
insert之後(語法)
drop trigger if exists 插入後觸發;
create trigger 插入後觸發 after insert on teacher for each row
begin
-- sql語句, 不能是select
end;
複製程式碼
我們的需求, 當訂單表裡新增訂單之後, 商品表裡的庫存需要相應減少
drop trigger if exists change_inventory;
create trigger change_inventory after insert on orders for each ROW begin
update goods
set
goods_inventory = goods_inventory - new.orders_buy_number
where
goods_id = new.orders_goods_id;
end;
insert into orders
set
orders_id = 3,
orders_goods_id = 1,
orders_buy_number = 3;
複製程式碼
中文版
drop trigger if exists 更改庫存;
create trigger 更改庫存 after insert on 訂單表 for each ROW begin
update 商品表
set
商品庫存 = 商品庫存 - new.訂單表裡的商品購買數量
where
商品ID = new.訂單裡的商品ID;
end;
insert into 訂單表
set
訂單ID = 3,
訂單裡的商品ID = 1,
訂單表裡的商品購買數量 = 3;
複製程式碼
![image.png](https://i.iter01.com/images/8df537d9b9ccbefe1b715e917ab8de98eee216963618e86aea842039e68e0a89.png)
![image.png](https://i.iter01.com/images/5ef8a3c561e9929811db24e4f516e1d4ef1e4c87c6e22db730e3183404823c32.png)
![image.png](https://i.iter01.com/images/4d9380eb67f6ddb32fef73d4443fdeb6a54134843ce845118ab8f78569afb94f.png)
![Snipaste_2019-04-13_17-48-39_看圖王.png](https://i.iter01.com/images/e9e29ce5675408c8aaa9903c254966cf5a51e75968f298a93f2c273cd466b715.png)
delete
如果訂單取消, 商品的庫存應該恢復
![image.png](https://i.iter01.com/images/360c00e0441e3e51c1b734bc92cc96fbf52df5eeae80888049033dd6c48f8ab0.png)
![image.png](https://i.iter01.com/images/b02e436656e57b0f8d42aa6e038e456cc0f9697d07f6ca6c6b8b52e03d36f2ba.png)
我們編寫一個觸發器, 如果訂單取消, 則電視機的庫存恢復到原來的20
drop trigger if exists recover_inventory;
create trigger recover_inventory after delete on orders for each row begin
update goods
set goods_inventory = goods_inventory + old.orders_buy_number
where goods_id = old.orders_goods_id;
end;
delete from orders where orders_id = 3;
複製程式碼
中文版
drop trigger if exists 恢復庫存;
create trigger 恢復庫存 after delete on 訂單表 for each row begin
update 商品表
set 商品庫存 = 商品庫存 + old.訂單表裡的商品購買數量
where 商品ID = old.訂單裡的商品ID;
end;
delete from 訂單表 where 訂單ID = 3;
複製程式碼
![image.png](https://i.iter01.com/images/02d88f772c05bf572bbd2ba5b581326697a9b0609ad81da293ca6ff1c3a257f8.png)
![image.png](https://i.iter01.com/images/fd126f059b29b9b706fd4dc92de5f0e0c2b4bb373c23e6c9e8abe8352d188de4.png)
檢視觸發器
檢視所有觸發器
show triggers;
複製程式碼
![image.png](https://i.iter01.com/images/c2e30fc1094af082a54a2e792b38b75effd361099ca3352fe0f9af0b6550f49c.png)
檢視觸發器建立語句
show create trigger 觸發器名稱;
複製程式碼
![image.png](https://i.iter01.com/images/90a7a95c12c547d3ec40776d19eb5e747f003ec1750c7e1bdacff24c7c3de878.png)
刪除&修改觸發器
觸發器不能修改, 只能先刪除, 再修改
drop trigger 觸發器名稱;
複製程式碼
最後說明
- 觸發器中, 只能有增刪改, 不能有查
- 觸發器中只能對非監聽的表, 進行增刪改, 避免死迴圈
- 觸發器的監聽物件,並不都有new和old
trigger監聽物件
![監聽物件.png](https://i.iter01.com/images/623e1ccdf86fdbb8126103c8482c710ed71624e1b0912e4693a2f8fb1523552c.png)