本篇文章采用的數(shù)據(jù)是把一個(gè)數(shù)據(jù)表中的數(shù)據(jù)導(dǎo)入另一個(gè)表里面的數(shù)據(jù)汇恤,此處不再展示。
- 參考文章【MySQL】觸發(fā)器入門
先做一個(gè)實(shí)例再解釋瘤运。實(shí)現(xiàn)
test1
只要執(zhí)行delete刪除
,就在觸發(fā)一個(gè)test1
觸發(fā)器属桦,test3
插入一條語(yǔ)句
// 下面的語(yǔ)句其實(shí)部分要分行菱阵,分行只是為了可讀性
create trigger test1 //test1觸發(fā)器名字
after // 觸發(fā)的時(shí)間 只有before和after
delete on test1 //delete還有insert update,共三種蚊逢。test1指的是test1數(shù)據(jù)表
for each row //此處是固定寫法层扶,意思是每次制定delete,就會(huì)出發(fā)下面的語(yǔ)句--刪除多少條烙荷,就會(huì)執(zhí)行下面的語(yǔ)句多少條
insert into test3 values (null,1,1,1); //這是觸發(fā)執(zhí)行的sql語(yǔ)句镜会,可以隨便寫
- 觸發(fā)器語(yǔ)法
在MySQL中终抽,創(chuàng)建觸發(fā)器語(yǔ)法如下:
CREATE TRIGGER trigger_name
trigger_time
trigger_event ON tbl_name
FOR EACH ROW
trigger_stmt
其中:
trigger_name:標(biāo)識(shí)觸發(fā)器名稱戳表,用戶自行指定;
trigger_time:標(biāo)識(shí)觸發(fā)時(shí)機(jī)昼伴,取值為 BEFORE 或 AFTER匾旭;
trigger_event:標(biāo)識(shí)觸發(fā)事件,取值為 INSERT圃郊、UPDATE 或 DELETE价涝;
tbl_name:標(biāo)識(shí)建立觸發(fā)器的表名,即在哪張表上建立觸發(fā)器描沟;
trigger_stmt:觸發(fā)器程序體飒泻,可以是一句SQL語(yǔ)句,或者用 BEGIN 和 END 包含的多條語(yǔ)句吏廉。
由此可見(jiàn)泞遗,可以建立6種觸發(fā)器,即:BEFORE INSERT席覆、BEFORE UPDATE史辙、BEFORE DELETE、AFTER INSERT、AFTER UPDATE聊倔、AFTER DELETE晦毙。
另外有一個(gè)限制是不能同時(shí)在一個(gè)表上建立2個(gè)相同類型的觸發(fā)器,因此在一個(gè)表上最多建立6個(gè)觸發(fā)器耙蔑。
BEGIN … END 詳解
在MySQL中见妒,BEGIN … END 語(yǔ)句的語(yǔ)法為:
BEGIN
[statement_list]
END
其中,statement_list 代表一個(gè)或多個(gè)語(yǔ)句的列表甸陌,列表內(nèi)的每條語(yǔ)句都必須用分號(hào)(;)來(lái)結(jié)尾须揣。
而在MySQL中,分號(hào)是語(yǔ)句結(jié)束的標(biāo)識(shí)符钱豁,遇到分號(hào)表示該段語(yǔ)句已經(jīng)結(jié)束耻卡,MySQL可以開始執(zhí)行了。
因此牲尺,解釋器遇到statement_list 中的分號(hào)后就開始執(zhí)行卵酪,然后會(huì)報(bào)出錯(cuò)誤,因?yàn)闆](méi)有找到和 BEGIN 匹配的 END谤碳。
這時(shí)就會(huì)用到 DELIMITER 命令(DELIMITER 是定界符溃卡,分隔符的意思),它是一條命令蜒简,不需要語(yǔ)句結(jié)束標(biāo)識(shí)塑煎,語(yǔ)法為:
DELIMITER new_delemiter --new_delemiter其實(shí)是一個(gè)新的符號(hào)
new_delemiter 可以設(shè)為1個(gè)或多個(gè)長(zhǎng)度的符號(hào),默認(rèn)的是分號(hào)(;)臭蚁,我們可以把它修改為其他符號(hào),如$:
DELIMITER $
在這之后的語(yǔ)句讯赏,以分號(hào)結(jié)束垮兑,解釋器不會(huì)有什么反應(yīng),只有遇到了$漱挎,才認(rèn)為是語(yǔ)句結(jié)束系枪。注意,使用完之后磕谅,我們還應(yīng)該記得把它給修改回來(lái)私爷。
一個(gè)完整的創(chuàng)建觸發(fā)器示例
假設(shè)系統(tǒng)中有兩個(gè)表:班級(jí)表 class(班級(jí)號(hào) classID, 班內(nèi)學(xué)生數(shù) stuCount)學(xué)生表 student(學(xué)號(hào) stuID, 所屬班級(jí)號(hào) classID)要?jiǎng)?chuàng)建觸發(fā)器來(lái)使班級(jí)表中的班內(nèi)學(xué)生數(shù)隨著學(xué)生的添加自動(dòng)更新,代碼如下:
DELIMITER $
create trigger tri_stuInsert after insert
on student for each row
begin
declare c int; //1.定義變量
set c = (select stuCount from class where classID=new.classID); //2.給變量賦值
update class set stuCount = c + 1 where classID = new.classID;
end$
DELIMITER ;
- 變量詳解
MySQL 中使用 declare
來(lái)定義一局部變量膊夹,該變量只能在BEGIN … END
復(fù)合語(yǔ)句中使用衬浑,并且應(yīng)該定義在復(fù)合語(yǔ)句的開頭,
即其它語(yǔ)句之前放刨,
- 定義變量語(yǔ)法如下:
declare var_name[,...] type [DEFAULT value]
其中:
var_name
為變量名稱工秩,同 SQL 語(yǔ)句一樣,變量名不區(qū)分大小寫;type
為 MySQL 支持的任何數(shù)據(jù)類型助币;可以同時(shí)定義多個(gè)同類型的變量浪听,用逗號(hào)隔開;變量初始值為 NULL眉菱,如果需要迹栓,可以使用 DEFAULT 子句提供默認(rèn)值,值可以被指定為一個(gè)表達(dá)式俭缓。
- 對(duì)變量賦值采用 SET 語(yǔ)句克伊,語(yǔ)法為:
SET var_name = expr [,var_name = expr] ...
- 查看和刪除觸發(fā)器
跟查看數(shù)據(jù)庫(kù),數(shù)據(jù)表一樣
show triggers;
drop trigger trigger_name;
// 我看他們資料這么寫
SHOW TRIGGERS [FROM schema_name]; //我測(cè)試后面添加數(shù)據(jù)庫(kù)名字刪除失敗
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name
- 觸發(fā)器的執(zhí)行順序
我們建立的數(shù)據(jù)庫(kù)一般都是 InnoDB 數(shù)據(jù)庫(kù)尔崔,其上建立的表是事務(wù)性表答毫,也就是事務(wù)安全的。這時(shí)季春,若SQL語(yǔ)句或觸發(fā)器執(zhí)行失敗洗搂,MySQL 會(huì)回滾事務(wù),有:
①如果 BEFORE 觸發(fā)器執(zhí)行失敗载弄,SQL 無(wú)法正確執(zhí)行耘拇。
②SQL 執(zhí)行失敗時(shí),AFTER 型觸發(fā)器不會(huì)觸發(fā)宇攻。
③AFTER 類型的觸發(fā)器執(zhí)行失敗惫叛,SQL 會(huì)回滾。