1. 程式人生 > >mysql---觸發器

mysql---觸發器

tracking ack 觸發 進一步 大於 jsb 表名 sql fill

觸發器(trigger)顧名思義能夠監視某種情況,當情況發生時,觸發某種操作

應用場景:

1、網購過程中。當提交商品訂單時,往訂單表中插入新記錄,觸發相應商品表的庫存做出相應降低。

2、支付過程中,確認支付時觸發驗證卡上剩余金額。

等等

以網購的情況舉例說明觸發器的作用:

現有商品表(goods)。包含商品id(goods_id)。商品名(goods_name)。庫存數量(goods_name)

技術分享

還有訂單表(order_table),包含商品id(goods_id)。購買數量(buy_num)

技術分享

假設往訂單表中插入一行記錄

技術分享

代表用戶購買了20個商品id為1的商品,即購買了20臺小米手機

與此同一時候,在邏輯上goods表中小米手機的庫存也應該減去20臺。

技術分享

這兩步事實上應該是一個總體。而我們如今是手工操作。怎樣讓第一步完畢後,第二步自己主動運行呢?

這就能夠用到觸發器的概念。第一條插入語句的運行。觸發了第二條改動庫存的SQL


觸發器四要素:

監視地點、監視事件、觸發時間、觸發事件

技術分享

監視地點:觸發器監視的對象是

監視事件:觸發器監視的事件僅僅能是增、刪、改

觸發時間:在監視事件之前還是之後

觸發事件:也僅僅能是增、刪、改

查看當前已有的觸發器:

show triggers;


觸發器的創建:

create trigger 觸發器名稱
after/befor (觸發時間)
insert/update/delete (監視事件)
on 表名 (監視地址)
for each row
begin
sql1;
..
sqlN;
end

須要註意點 是,所須要觸發的SQL語句都要以‘;’結束。

end後面也須要有分界符。但不能再是‘;‘。

所以創建觸發器之前須要先改動分界符

delimiter 分界符


如今利用觸發器對上面的樣例進行改動

技術分享

這個觸發器以完畢:當訂購了20個商品id為1的商品時。goods表的庫存會同步減去20。我們來看看效果

技術分享

商品id為1的商品庫存的確減去了20。觸發器的確完畢了任務,但這個觸發器並不智能。他僅僅能處理商品id為1,購買數量為20的情況。要想應對其它情況須要獲得提交訂單的記錄才行。


觸發器引用行變量:

技術分享

技術分享

對於insert。插入一行後出現了一個新行用new表示,在觸發器中能夠通過new.列名來引用插入行各個字段的值

對於delete。刪除一行後之前的那行不見了。用old表示。在觸發器中能夠通過old.列名來引用被刪除行各個字段的值

對於update。改動一行後舊的一樣用old表示,新的一行用new表示,在觸發器中能夠通過new.列名來引用改動後行各個字段的值,old.列名來引用改動前各個字段的值。

知道這些後,對觸發器進行進一步改動

技術分享

技術分享

再看一下效果

沒有提交訂單前商品表的情況

技術分享

提交兩個訂單

技術分享

商品表變化

技術分享

可見觸發器的確發生了作用


觸發器after和before的差別:

after是先完畢增刪改再觸發

before是在增刪改之前將以推斷

前面已經討論過after的情況。如今假設提交了一個訂單購買了100個id為4的商品,然而三星手機庫存僅有30個。假設依照上面的觸發器。最後庫存會變成-70。這顯然是不正確的。所以這時候能夠利用before來對輸入進行推斷。假設購買數量大於庫存則僅僅能購買所剩下的商品。

技術分享

技術分享

如今購買100個id為4的商品

技術分享

再看看訂單表

技術分享

實際購買的僅僅有30而不是100

mysql---觸發器