第一章:mysql觸發器
1.所謂觸發器,就是指設置好某個表的某個操作[insert ,update ,delete]時候,同時觸發的一個操作[insert,update,delete]
使用場景:比如商城訂單操作,當用戶完成下單操作后,需要對商品表進行庫存減一操作,這時候我們可以采用PHP來做相應的邏輯處理,但如果是使用mysql觸發器來操作,就可以節省我們寫PHP邏輯代碼的時間
我們如果要深入理解mysql觸發器,必須掌握觸發器的四要素:
**1.監控的表[數據庫中的某張表]**
**2.監視的事件[某張表表的insert,update,delete操作]**
**3.觸發時間在 insert,update,delete 等操作前還是操作后**
**4.需要觸發的事件[insert,update,delete]**
基本格式:
```
delimiter $$ --delemiter:聲明定界符為 $$
create trigger orderMinusOne --創建一個觸發器:orderMinusOne觸發器名稱
after|before --觸發時間
insert|delete|update --監聽的事件
on tabName --監聽的表
for each row --行級觸發器。mysql不支持語句觸發器,所以必須寫for each row,每行受影響,觸發器都執行
begin --開始 xxx
#SQL語句
end $$ --結束
delimiter;
```
一個栗子:模擬商品下單場景,用戶下單成功之后,根據購買數量相應的商品表商品數量減去購買數。
商品表:
```
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for tb_goods
-- ----------------------------
DROP TABLE IF EXISTS `tb_goods`;
CREATE TABLE `tb_goods` (
`goods_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品id',
`goods_num` int(11) unsigned NOT NULL COMMENT '商品數量',
`goods_price` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '商品價格',
`goods_name` varchar(255) NOT NULL DEFAULT '' COMMENT '商品名',
`is_rease` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否發布,0發布,1不發布',
PRIMARY KEY (`goods_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
訂單表:
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for tb_order
-- ----------------------------
DROP TABLE IF EXISTS `tb_order`;
CREATE TABLE `tb_order` (
`order_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '訂單id',
`goods_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '訂單id',
`buy_num` int(11) NOT NULL DEFAULT '0' COMMENT '購買個數',
`order_number` varchar(19) NOT NULL DEFAULT '' COMMENT '訂單編號',
`is_valid` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否有效,0有效,1無效',
PRIMARY KEY (`order_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
```
因為觸發器會監視mysql的insert,delete,update等操作,所以如果表中新增一列或者減少一列都會被記錄,如果需要找到新增列[insert]的字段字,可以使用 new.字段 表示,相應的減少列[delete]操作可以用 old.字段表示。
創建觸發器:
```
delimiter $$ --delemiter $$ 聲明定界符為 delimiter
create trigger orderMinusOne --創建一個觸發器:orderMinusOne觸發器名稱
after --觸發時間
insert --監聽的事件
on tb_order --監聽的表
for each row
begin --開始
update tb_goods set goods_num = goods_num - new.buy_num where goods_id = new.goods_id
-- 商品表商品數量減去購買數量的值
end $$ --以 $$ 分隔符結束
delimiter;
```
注:對于insert操作,只能使用new.字段,對于delete操作,只能使用old.字段,而update操作,old.字段,new.字段都可以使用
```
查看我們創建的觸發器:
show triggers;
```
```
刪除觸發器命令:
drop trigger triggerName;
```
當然,這只是一個簡單的栗子,實際應用場景要比這復雜的多,比如,如果庫存字段我們沒有設置為非負數極可能出現超賣的情況。除了邏輯代碼與限制字段非負,用觸發器我們同樣也可以實現。
一個符合生產情況的栗子:
```
delimiter $$ --delemiter $$ 聲明定界符為 delimiter
create trigger orderMinusOne --創建一個觸發器:orderMinusOne觸發器名稱
before --觸發時間
insert --監聽的事件
on tb_order --監聽的表
declare
goodsnum int --declare 聲明一個int類型的goodsnum的變量,用于后續存儲查詢出來的變量
for each row
begin --開始
select goods_num into goodsnum from tb_goods where goods_id = new.goods_id --將商品表的庫存查詢出來賦值給goods_num
if new.buy_num > goodsnum then --判斷,如果購買數量大于庫存量的話
set new.buy_num = goodsnum --讓購買數量等于庫存量
end if
update tb_goods set goods_num = goods_num - new.buy_num where goods_id = new.goods_id --執行商品表庫存減操作
end $$
delimiter;
```
[TOC]
[TOC]
[TOC]