最近數據庫方面遇到了瓶頸,查數據寫出來的sql語句自己都覺得效率不高,但也不知道怎麼去優化,於是乎決定要把mysql系統的學一遍,今天學到了mysql的觸發器。下面咱就說下俺的理解。
1.什麼是觸發器?爲什麼要用?
mysql觸發器說白了就是一段嵌入到mysql的程序,在你對錶進行增刪改時觸發該程序,同時響應另一張表做出相同的操作。
舉個例子來說:有一張商品表和一張訂單表,當購買商品時,要相應的往訂單表裏插入數據,同時商品表裏的商品數量要減少。這個我們在程序裏可以解決,但是用觸發器該怎麼做呢?
2.觸發器的創建
首先創建兩張表吧,goods表和order表
create table goods( gid int unsigned not null auto_increment primary key, name varchar(30) not null default '', num int )engine innodb charset utf8;
create table order( oid int unsigned not null auto_increment primary key, gid int, amount int )engine innodb charset utf8;
好了,簡單的建了兩張表。下面開始建觸發器
①觸發器的五要素
觸發器的名稱、觸發時間、監聽的事件、觸發地點、觸發的事件
delimiter $ create trigger p1 #觸發器名稱 before(after) insert #觸發時間before或者after,監聽的insert事件 on order #觸發的地點,order表 for each row #mysql是行級觸發器 begin update goods set num=num-new.amount where gid=new.gid;#觸發事件 new或old可以用來替代原來的和新的數據 end$
那麼當向order表裏插入數據時,該觸發器就會響應,改變goods表裏對應的商品數量。
上面的例子,如果商品表裏的商品數量爲負了怎麼辦?如果爲負,假如讓order表裏的amount爲剩餘的商品數量。下面創建觸發器
delimiter $ create trigger p2 after insert on order for each row begin declare snum int; select num into snum from goods where gid=new.gid; if new.amount>snum #如果商品數量不足,則有多少購買多少 set new.amount=snum; end if; update goods set num=num-new.amount where gid=new.gid; end$
那麼當插入數據時,會不會正常執行呢?不好意思,結果報錯了,報了什麼錯?
ERROR 1362 (HY000): Updating of NEW row is not allowed in after trigger
意思是不允許在事後觸發器修改新的記錄,也就是已經insert數據了,又試圖立馬修改insert後的數據,這是不被允許的,那怎麼辦呢?
我們只需要將上面的after insert改爲before insert,即事前修改就行了。