觸發(fā)器介紹:
觸發(fā)器是個(gè)特殊的存儲(chǔ)過(guò)程,它的執(zhí)行不是由程序調(diào)用衔肢,也不是手工啟動(dòng),而是由事件來(lái)觸發(fā)豁翎,比如當(dāng)對(duì)一個(gè)表進(jìn)行操作( insert角骤,delete, update)時(shí)就會(huì)激活它執(zhí)行心剥。觸發(fā)器經(jīng)常用于加強(qiáng)數(shù)據(jù)的完整性約束和業(yè)務(wù)規(guī)則等
使用觸發(fā)器的優(yōu)點(diǎn):
- 可以來(lái)檢查或預(yù)防壞的數(shù)據(jù)進(jìn)入數(shù)據(jù)庫(kù)邦尊。
- 可以改變或取消INSERT、UPDATE刘陶、以及DELETE語(yǔ)句胳赌。
- 可以在一個(gè)會(huì)話中監(jiān)視數(shù)據(jù)改變的動(dòng)作。
使用觸發(fā)器的缺點(diǎn):
- MySQL觸發(fā)器始終時(shí)基于表中的一條記錄觸發(fā)匙隔,而不是一組SQL語(yǔ)句疑苫。因此,如果需要變動(dòng)整個(gè)數(shù)據(jù)集而數(shù)據(jù)集數(shù)據(jù)量又較大時(shí)纷责,觸發(fā)器效果會(huì)非常低捍掺。
- 每一個(gè)表的一個(gè)事件只能定義一個(gè)觸發(fā)器,而且表必須引用永久性表,不能將觸發(fā)程序與TEMPORARY表或視圖關(guān)聯(lián)起來(lái)再膳。
- 由于MySQL觸發(fā)器基于行觸發(fā)的特性挺勿,因此對(duì)于批量操作并不適合使用觸發(fā)器
使用觸發(fā)器實(shí)現(xiàn)的業(yè)務(wù)邏輯在出現(xiàn)問(wèn)題時(shí)很難進(jìn)行定位,特別是設(shè)計(jì)到多個(gè)觸發(fā)器的情況 - 協(xié)同開發(fā)時(shí)喂柒,寫業(yè)務(wù)層代碼如果不清楚數(shù)據(jù)庫(kù)觸發(fā)器的細(xì)節(jié)不瓶,容易搞不清到底觸發(fā)了那些觸發(fā)器
- 大量使用觸發(fā)器會(huì)導(dǎo)致代碼結(jié)構(gòu)容易被打亂,閱讀源碼困難
創(chuàng)建觸發(fā)器:
- 命令模式如下:
create
[definer = { user | CURRENT_USER }]
trigger trigger_name
{before | after } {insert | update | delete}
ON table_name FOR EACH ROW
[{follows | precedes}] other_trigger_name
trigger_body
說(shuō)明:
definer:指定用戶名灾杰。
trigger_name: 觸發(fā)器名稱且名稱最多不超過(guò)64個(gè)字符
before|after. 可以設(shè)置為事件發(fā)生前或后觸發(fā)
insert:將新行插入表時(shí)激活觸發(fā)程序蚊丐,例如,通過(guò)insert艳吠、load data和replace語(yǔ)句麦备。
update:更改某一行時(shí)激活觸發(fā)程序
delete:從表中刪除某一行時(shí)激活觸發(fā)程序,例如昭娩,通過(guò)delete和replace語(yǔ)句凛篙。
table_name:觸發(fā)器是屬于某一個(gè)表的:當(dāng)在這個(gè)表上執(zhí)行插入、更新或刪除操作的時(shí)候就導(dǎo)致觸發(fā)器的激活栏渺。我們不能給同一張表的同一個(gè)事件安排兩個(gè)觸發(fā)器呛梆,而且必須引用永久性表,不能將觸發(fā)程序與TEMPORARY表或視圖關(guān)聯(lián)起來(lái)。
FOR EACH ROW 觸發(fā)間隔通知觸發(fā)器每隔一行執(zhí)行一次動(dòng)作,而不是對(duì)整個(gè)表執(zhí)行一次啼县。
關(guān)于舊的和新創(chuàng)建的列的標(biāo)識(shí)
在觸發(fā)器的SQL語(yǔ)句中灾搏,你可以關(guān)聯(lián)表中的任意列角寸。但你不能僅使用列的名稱去標(biāo)識(shí)朝聋,那會(huì)使系統(tǒng)混淆虐沥,因?yàn)槟抢锟赡軙?huì)有列的新名(這可能正是你要修改的腿宰,你的動(dòng)作可能正是要修改列名)雁刷,還有列的舊名存在覆劈。因此你必須用這樣的語(yǔ)法來(lái)標(biāo)識(shí): "NEW . column_name"或者"OLD . column_name".這樣在技術(shù)上處理(NEW | OLD . column_name)新和舊的列名屬于創(chuàng)建了過(guò)渡變量("transition variables")。
對(duì)于insert語(yǔ)句,只有NEW是合法的沛励;對(duì)于delete語(yǔ)句责语,只有OLD才合法;而update語(yǔ)句可以在和NEW以及OLD同時(shí)使用目派。
ex:
--插入用戶數(shù)據(jù)到user表中后坤候,往user_temp表中同步一份用戶數(shù)據(jù)
create definer= CURRENT_USER trigger insert_sync_user_data
after insert on user
for each row
begin
set @username = NEW.name;
insert into user_temp(name) value(@username);
end;
查看觸發(fā)器:
- 命令模式如下:
SHOW TRIGGERS [{FROM | IN} db_name] [LIKE 'pattern' | WHERE expr]
ex:
--創(chuàng)建一個(gè)test觸發(fā)器
create definer = CURRENT_USER trigger test after insert on user for each row
set @name = NEW.name;
--查看全部的觸發(fā)器
show triggers;
--查看以tes開頭的觸發(fā)器
show trigger like 'tes%'\G;
--查看test觸發(fā)器
show create trigger test;
刪除觸發(fā)器:
- 命令模式如下:
drop trigger [if exists] [schema_name.]trigger_name
ex:
--刪除insert_sync_user_data觸發(fā)器
drop trigger if exists insert_sync_user_data;
--刪除test觸發(fā)器
drop trigger if exists test;