[MySQL光速入門]026 觸發器 trigger!!!

貓哥的技術部落格發表於2019-04-18

什麼是觸發器

就是trigger(扳機), 一碰就動, 一觸即發, 就叫觸發器

跟儲存過程類似, 也是主要用於增, 刪, 改

事先為某張表繫結一段程式碼, 當表中的某些內容發生改變的時候(對錶進行增刪改), 系統就會自動觸發程式碼執行

監聽, 只要...就觸發, 然後執行...

觸發器.png

為什麼需要觸發器?

有些sql語句, 或者資料庫操作, 在邏輯上是緊密相關, 不可分割的, 需要一起執行

建立觸發器

建立觸發器.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

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

image.png

image.png

Snipaste_2019-04-13_17-48-39_看圖王.png

delete

如果訂單取消, 商品的庫存應該恢復

image.png

image.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

image.png

檢視觸發器

檢視所有觸發器

show triggers;
複製程式碼

image.png

檢視觸發器建立語句

show create trigger 觸發器名稱;
複製程式碼

image.png

刪除&修改觸發器

觸發器不能修改, 只能先刪除, 再修改

drop trigger 觸發器名稱;
複製程式碼

最後說明

  1. 觸發器中, 只能有增刪改, 不能有查
  2. 觸發器中只能對非監聽的表, 進行增刪改, 避免死迴圈
  3. 觸發器的監聽物件,並不都有new和old

trigger監聽物件

監聽物件.png

快速跳轉

相關文章