trigger 触发器(mysql)
生活随笔
收集整理的這篇文章主要介紹了
trigger 触发器(mysql)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
/*
觸發器 tigger
引出觸發器:在進行數據庫應用軟件的開發的時候,我們有時候會碰到表中的某些數據改變,同事希望引起其他相關數據改變的需求,這時候就需要使用觸發器。運用觸發器可以簡化程序,增加程序的靈活性
觸發器是什么?觸發器是一種特殊的事務,可以監視某種數據操作(增、刪、改),并觸發相關操作(增、刪、改)
觸發器應用場景:訂單產生,庫存減少客戶消費,積分變化等觸發器的創建語法四要素:監視地點(table) 監視事件(insert、update、delete) 觸發時間(after、before) 觸發事件(insert、update、delete)查看已有triggers:show triggers 刪除觸發器drop tigger tiggername觸發器使用監視表改變數據: new(新行) old(舊行) *//*
需求:
商品表:goods
訂單表:ord當下一個訂單時,對應的商品要相應減少(買幾個商品就少幾個庫存)分析:
監視誰:ord
監視動作:insert
出發時間:after
觸發事件:update
*/
drop table goods;
drop table ord;
create table goods
(gid int,name varchar(20),num smallint
);
create table ord
(oid int,gid int,munch smallint
);insert into goods
values (1,'cat',34),(2,'dog',65),(3,'pig',21);--現在我希望我下訂單的時候貓的數量減少2只。
--第一個觸發器
create trigger t1
after
insert
on ord
for each row
begin
update goods set num=num-2 where gid=1;
end;--買2只貓,我們發現goods表貓的數量自己減少了2個
insert into ord values (123,1,2);
select * from goods;
--觸發器完成了我們的要求嗎?我再生成一個買3只豬的訂單,發現變得還是貓,還是減少兩個
insert into ord values (124,3,3);
select * from goods;
--前面的觸發器無法實現我們的要求是因為我們在 update goods set num=num-2 where gid=1; 改變是固定的
-- 可以使用參數嗎?在觸發器中,如果可以,應該使用什么呢?
-- 被監視的語句中的數據元素可以被我們得到嗎?-- 新增的列使用new得到,刪除的列使用old得到
create trigger t12
after
insert
on ord
for each row
begin
update goods set num=num-new.munch where gid=new.gid;
end;
--添加第二個觸發器失敗,因為不能針對同一個列,在同一個操作,同一個時刻有兩個觸發器,所以我們將前面的觸發器刪除
show triggers;
drop trigger t1;--新增了得到了觸發器。
--為了便于顯示,我先將訂單表清空
truncate ord;
select * from ord;
select * from goods;
--現在我想要訂單買2只狗
insert into ord values (123,2,2);
--買一只貓
insert into ord values (124,1,1);
--發現現在的觸發器滿足我們的需求了--舉一反山,使用old關鍵字觸發器控制當訂單表刪除訂單的時候,將訂單中的所屬動物返還create trigger t3
after
delete
on ord
for each row
begin
update goods set num=num+old.munch where gid=old.gid;
end;delete from ord where oid=124;
-- 發現達到我們效果了-- 訂單改變的時候goods也隨之改變
create trigger t4
after
update
on ord
for each row
begin
update goods set num=num+old.munch-new.munch where gid=new.gid;
end;select * from ord;
select * from goods;
update ord set munch=17 where gid=2;--before目前似乎并沒有看出與after的區別
--一個問題:如果剩余3頭豬,但是客戶買了十頭豬會發生什么情況?能否預防
-- 發現現在dog有21頭,如果我訂單買32頭豬,試試
insert into ord values (124,3,32);
select * from goods;-- 我發現豬變成負數了,這時候,我覺得有必要在訂單增加后做一些判斷以及對應的操作
-- 我先將錯誤訂單刪除,退回到前面的狀態
delete from ord where oid=124;
--現在,我希望修改前面的t12觸發器,使他達到我的要求
--先刪除再添加
drop trigger t12;
create trigger t2
after
insert
on ordfor each row
begindeclare rnum int;
select num into rnum from goods where gid=new.gid;if new.munch>rnum
thenset new.munch=rnum;
end if;update goods set num=num-new.munch where gid=new.gid;end;
--我們添加t2觸發器報錯。提示:updating of new rows is not allowed in after trigger
-- 這是因為我們使用的是after關鍵字,然后在觸發器使用的時候new.munch的值已經確定了并且執行了(關鍵是執行了),就不能更改了,所以報錯。所以這里應該將after改為beforecreate trigger t2
before
insert
on ordfor each row
begindeclare rnum int;
select num into rnum from goods where gid=new.gid;if new.munch>rnum
thenset new.munch=rnum;
end if;update goods set num=num-new.munch where gid=new.gid;
end;--我們再測試一下,觸發器生效了,改變了訂單和goods表,避免了負數
select * from ord;
select * from goods;
insert into ord values (124,3,32);
?
/*我們建立觸發器時候的for each row有什么作用呢?為什么要使用它呢?從字面上理解,指向每一列。其實 for each是指定觸發器為行級觸發器,行級觸發器指的就是每一行對應的改變都會跑一次觸發器。就是在一次執行多行語句的操作中會跑多次觸發器 在oracle中,觸發器分語句級觸發器和行級觸發器,如果不寫for each row表示語句級觸發器,只會被觸發一次 */ -- 測試一下 select * from ord; --寫一個表記錄觸發次數 create table ct(coun int); -- 改變一下那個觸發條件為update的觸發器 drop trigger t4; create trigger t4 after update on ord for each row begin update goods set num=num+old.munch-new.munch where gid=new.gid; insert into ct values(5); end; --我先執行一次改變,看下效果 update ord set munch=10 where gid=2; select * from ct; --插入了一次 update ord set munch=0; select * from ct; -- 檢測出插入了兩次-- 實驗一下語句級別觸發器 ,真是不巧,mysql暫時不支持語句級別觸發器 drop trigger t4; create trigger t4 after update on ord -- for each row begin update goods set num=num+old.munch-new.munch where gid=new.gid; insert into ct values(3); end;?
總結
以上是生活随笔為你收集整理的trigger 触发器(mysql)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转: 七牛云的开源播放器的使用指南
- 下一篇: strftime()和strptime的