Mysql觸發器、檢視、儲存過程詳解(例項)
阿新 • • 發佈:2019-01-24
/*觸發器trigger*/
觸發器的概念:監視某種情況並出發某種操作例如:
一個電子商城商品表goods簡稱g:
主鍵 商品名 庫存
1 電腦 28
2 手錶 120
訂單表o:
訂單主鍵 訂單外來鍵 購買數量
1 2 3
2 1 5
完成下單與減少庫存邏輯:
Insert into o(商品外來鍵, 購買數量) values (2, 3);
Update g set 庫存 = 庫存-3 if id = 2;
這兩個邏輯可以堪稱一個整體,或者說insert肯定會引發update
這就可以用到觸發器,我們可以監視某個表的變化,當變化發生,觸發一個表的操作。
要注意:
觸發器可以監視:增刪改操作,沒有查
觸發器可以觸發:增刪改操作,沒有查
例項:
#建立商品表 create table g( id int, name varchar(10), num int )charset utf8; #建立訂單表 create table o( oid int; gid int; much int; )charset utf8; #新增商品表 insert into g values(1, '豬', 22), (2, ‘'羊', 10), (3, '狗', 13); #買三隻樣 insert into o values(1, 2 3); #減少商品表的庫存(更新) update g num = num -3 where id = 2;
觸發器四要素:
監視地點:o表
監視操作:insert
觸發操作:update
觸發時間:after
因此上面的整個過程可以做成觸發器(語法):
delimiter $;
create tigger tiggerName
After/Before insert/update/detele on tableName
For each row //這句是固定的為行觸發器,瞭解oracle資料庫還有表觸發器
begin
insert/update/detele (sql語句); /*可以多句*/
end$
delimiter ;;
根據上面的例項一個可用的觸發器:
對於insert而言,新增的行用new表示,行中每一列的值用 new.列名 來表示
這裡增設一種情況:萬一使用者撤銷了訂單:delimiter $; create tigger tg1 after insert on o for each row begin update g set num = num - new.much where id = new.gid; end$
所以,修改訂單的時候,庫存也要改變
監視地點:o表
監視操作:detele
觸發操作:update
觸發時間:after
有了四要素,寫tigger就很清楚了
對於detele而言,新增的行用old表示,行中每一列的值用 old.列名 來表示
create tigger tg2
after detele on o
for each row
befor
update g set num = num + old.much where id = old.gid;
end$
再來看修改訂單的數量時,庫存相應改變:對於update而言,被修改的行修改前用old表示,行中每一列的值用 old.列名 來表示 修改之後的
行用new表示,行中每一列的值用 new.列名 來表示
create tigger tg3
after detele on o
for each row
befor
update g set num = num + old.much - new.much where id = old.gid;
end$
/*檢視*/
儲存查詢結果的虛擬表Create view 檢視名 as select語句
drop view 檢視名
alter view 檢視名 as select語句
(1)為什麼要檢視:
1.簡化查詢
2.可以進行許可權控制
3.大資料分表的時候可用(id%表數+1、檢視)
注意:
修改表檢視改變
修改視圖表不一定改變(因為表可能是眾多行運算以後的結果,即一對多的情況,相反一對一的情況可以修改表但也要注意:對於insert檢視必須包含沒有預設值的列)(2)檢視algorithm :
merge 就是一條語法規則,沒有建立表,對檢視的操作實際是和檢視的語法規則合併形成一條select語句對原表的操作
temptable建立一張臨時表,對檢視的操作就是對臨時表的操作
undefine由系統自己決定規則。
/*儲存過程*/
儲存過程主要為了提高效率,實現語句的批處理執行。但是in|out|inout修改變數對原表的影響這裡不討論
SHOW procedure status
drop procedure 儲存過程名字
delimiter $;
create procedure name(in | out| inout)
begin
select * from tablename;
/*批語句*/
end$