MySQL(十一)之触发器
上一篇介紹的是比較簡(jiǎn)單的視圖,其實(shí)用起來是相對(duì)比較簡(jiǎn)單的,以后有什么更多的關(guān)于視圖的用法,到時(shí)候在自己補(bǔ)充。接下來讓我們一起了解一下觸發(fā)器的使用!
一、觸發(fā)器概述
1.1、什么是觸發(fā)器
觸發(fā)器(Trigger):監(jiān)視某種情況,并觸發(fā)某種操作。在MySQL Server里面也就是對(duì)某一個(gè)表的一定的操作,觸發(fā)某種條件(Insert,Update,Delete 等),從而自動(dòng)執(zhí)行的一段程序。
注意:你必須擁有相當(dāng)大的權(quán)限才能創(chuàng)建觸發(fā)器(CREATE TRIGGER),如果你已經(jīng)是Root用戶,那么就足夠了。這跟SQL的標(biāo)準(zhǔn)有所不同。
1.2、觸發(fā)器作用
那么為什么要使用數(shù)據(jù)庫對(duì)象觸發(fā)器呢?在具體開發(fā)項(xiàng)目時(shí),經(jīng)常會(huì)遇到如下實(shí)例:
1)在學(xué)生表中擁有字段學(xué)生姓名,字段學(xué)生總數(shù),每當(dāng)添加一條學(xué)生信息時(shí),學(xué)生的總數(shù)就必須同時(shí)更改。
2)在學(xué)生表中還會(huì)有學(xué)生姓名的縮寫,學(xué)生住址等字段,添加學(xué)生信息時(shí),往往需要檢查電話、郵箱等格式是否正確。
上面的例子使用觸發(fā)器完成時(shí)具有這樣的特點(diǎn),需要在表發(fā)生改變時(shí),自動(dòng)進(jìn)行一些處理。MySQL在觸發(fā)DELETE/UPDATE/INSERT語句時(shí)就會(huì)自動(dòng)執(zhí)行所設(shè)置的操作,其他SQL語句則不會(huì)激活觸發(fā)器。
1.3、觸發(fā)器四要素
監(jiān)視地點(diǎn):table
監(jiān)聽事件:insert/update/delete
觸發(fā)時(shí)間:after/before
觸發(fā)事件:insert/update/delete
二、觸發(fā)器用法
2.1、觸發(fā)器語法
CREATE TRIGGER <觸發(fā)器名稱>? --觸發(fā)器必須有名字,最多64個(gè)字符,可能后面會(huì)附有分隔符.它和MySQL中其他對(duì)象的命名方式基本相象.
{ BEFORE | AFTER }? --觸發(fā)器有執(zhí)行的時(shí)間設(shè)置:可以設(shè)置為事件發(fā)生前或后。
{ INSERT | UPDATE | DELETE }? --同樣也能設(shè)定觸發(fā)的事件:它們可以在執(zhí)行insert、update或delete的過程中觸發(fā)。
ON <表名稱>? --觸發(fā)器是屬于某一個(gè)表的:當(dāng)在這個(gè)表上執(zhí)行插入、 更新或刪除操作的時(shí)候就導(dǎo)致觸發(fā)器的激活. 我們不能給同一張表的同一個(gè)事件安排兩個(gè)觸發(fā)器。
FOR EACH ROW? --觸發(fā)器的執(zhí)行間隔:FOR EACH ROW子句通知觸發(fā)器 每隔一行執(zhí)行一次動(dòng)作,而不是對(duì)整個(gè)表執(zhí)行一次。
<觸發(fā)器SQL語句>? --觸發(fā)器包含所要觸發(fā)的SQL語句:這里的語句可以是任何合法的語句, 包括復(fù)合語句,但是這里的語句受的限制和函數(shù)的一樣。
簡(jiǎn)單的寫就是這樣:
create trigger tg_name after/before insert/update/delete on tablefor each row ####這句話在MySQL中是固定的beginsql語句;end$?
分析:由于在以上代碼段中的“sql語句;”是以分號(hào)結(jié)尾,所以需要將MySQL中的結(jié)尾標(biāo)志換成“$”,更換MySQL命令結(jié)束標(biāo)志的命令:delimiter $;
? 以上觸發(fā)器語法中的各個(gè)段的顏色與四要素對(duì)應(yīng)查看理解。
2.2、創(chuàng)建觸發(fā)器
1)創(chuàng)建兩張表
create table tb_goods(id int primary key auto_increment,name varchar(20),num int);create table tb_orders(id int primary key auto_increment,good_id int,much int);?
2)在商品表中插入數(shù)據(jù)
insert into tb_goods(name,num)values('商品1',10),('商品2',10),('商品3',10);?
3)假如我們賣了3個(gè)商品1
沒有觸發(fā)器:
往訂單表中插入一條記錄:insert into tb_orders(good_id,much) values(1,3);
更新商品表中商品1的剩余數(shù)量:update tb_goods set num=num-3 where id=1;
創(chuàng)建觸發(fā)器:
create trigger tg_1 after insert on tb_ordersfor each row
begin
update tb_goods set num=num-3;
end$
?
這個(gè)時(shí)候如果執(zhí)行insert into tb_orders(good_id,much) values(1,3);會(huì)發(fā)現(xiàn)商品的數(shù)量變?yōu)?了,說明在插入一條訂單的時(shí)候,觸發(fā)器自動(dòng)做了更新操作。
2.3、觸發(fā)器對(duì)值得引用
上述觸發(fā)器有一個(gè)問題,因?yàn)樵谟|發(fā)器中寫死了num和id,所以不管買哪個(gè)商品,最終更新的都是商品1的數(shù)量。這個(gè)時(shí)候,需要將觸發(fā)器中的值變?yōu)閯?dòng)態(tài)獲取。
對(duì)于insert來說,新插入的行用new來表示,行中的每一列的值用“new.列名”來表示:
新建能動(dòng)態(tài)獲取值的觸發(fā)器:
create trigger tg_2 after insert on tb_ordersfor each rowbeginupdate tb_goods set num=num-new.much where id=new.id;end$?
刪除第一個(gè)觸發(fā)器:drop trigger tg_1;
插入一條訂單記錄:insert into tb_orders(good_id,much) values(2,3)$
執(zhí)行完發(fā)現(xiàn)商品的數(shù)量變?yōu)?了,這樣子就是合適的。
三、觸發(fā)器實(shí)例
1)創(chuàng)建表tab1
DROP TABLE IF EXISTS tab1;CREATE TABLE tab1(tab1_id varchar(11));2)創(chuàng)建表tab2
DROP TABLE IF EXISTS tab2;CREATE TABLE tab2(tab2_id varchar(11));3)創(chuàng)建觸發(fā)器:t_afterinsert_on_tab1
DROP TRIGGER IF EXISTS t_afterinsert_on_tab1; CREATE TRIGGER t_afterinsert_on_tab1 AFTER INSERT ON tab1 FOR EACH ROW BEGINinsert into tab2(tab2_id) values(new.tab1_id); END;4)想tab1插入數(shù)據(jù)
INSERT INTO tab1(tab1_id) values('0001');5)查看變化
SELECT * FROM tab1; SELECT * FROM tab2;?
超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的MySQL(十一)之触发器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python-ConfigParser模
- 下一篇: 新加坡樟宜机场将进入“刷脸”时代 自助通