觸發(fā)器的使用

本篇文章采用的數(shù)據(jù)是把一個(gè)數(shù)據(jù)表中的數(shù)據(jù)導(dǎo)入另一個(gè)表里面的數(shù)據(jù),此處不再展示。


先做一個(gè)實(shí)例再解釋。實(shí)現(xiàn)test1只要執(zhí)行delete刪除,就在觸發(fā)一個(gè)test1觸發(fā)器,test3插入一條語句

// 下面的語句其實(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ā)下面的語句--刪除多少條,就會(huì)執(zhí)行下面的語句多少條
insert into test3 values (null,1,1,1);  //這是觸發(fā)執(zhí)行的sql語句,可以隨便寫
test3原本5條數(shù)據(jù)
test1刪除6條后,test3增加6條
  • 觸發(fā)器語法
在MySQL中,創(chuàng)建觸發(fā)器語法如下:
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語句,或者用 BEGIN 和 END 包含的多條語句。

由此可見,可以建立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 語句的語法為:

BEGIN
[statement_list]
END

其中,statement_list 代表一個(gè)或多個(gè)語句的列表,列表內(nèi)的每條語句都必須用分號(hào)(;)來結(jié)尾。
而在MySQL中,分號(hào)是語句結(jié)束的標(biāo)識(shí)符,遇到分號(hào)表示該段語句已經(jīng)結(jié)束,MySQL可以開始執(zhí)行了。
因此,解釋器遇到statement_list 中的分號(hào)后就開始執(zhí)行,然后會(huì)報(bào)出錯(cuò)誤,因?yàn)闆]有找到和 BEGIN 匹配的 END。

這時(shí)就會(huì)用到 DELIMITER 命令(DELIMITER 是定界符,分隔符的意思),它是一條命令,不需要語句結(jié)束標(biāo)識(shí),語法為:
DELIMITER new_delemiter --new_delemiter其實(shí)是一個(gè)新的符號(hào)
new_delemiter 可以設(shè)為1個(gè)或多個(gè)長度的符號(hào),默認(rèn)的是分號(hào)(;),我們可以把它修改為其他符號(hào),如$:
DELIMITER $
在這之后的語句,以分號(hào)結(jié)束,解釋器不會(huì)有什么反應(yīng),只有遇到了$,才認(rèn)為是語句結(jié)束。注意,使用完之后,我們還應(yīng)該記得把它給修改回來。

一個(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ā)器來使班級(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 來定義一局部變量,該變量只能在BEGIN … END 復(fù)合語句中使用,并且應(yīng)該定義在復(fù)合語句的開頭,
即其它語句之前,

  • 定義變量語法如下:
declare var_name[,...] type [DEFAULT value]

其中:
var_name為變量名稱,同 SQL 語句一樣,變量名不區(qū)分大小寫;type 為 MySQL 支持的任何數(shù)據(jù)類型;可以同時(shí)定義多個(gè)同類型的變量,用逗號(hào)隔開;變量初始值為 NULL,如果需要,可以使用 DEFAULT 子句提供默認(rèn)值,值可以被指定為一個(gè)表達(dá)式。

  • 對(duì)變量賦值采用 SET 語句,語法為:
SET var_name = expr [,var_name = expr] ...
  • 查看和刪除觸發(fā)器
    跟查看數(shù)據(jù)庫,數(shù)據(jù)表一樣
show triggers;
drop trigger trigger_name;

// 我看他們資料這么寫
SHOW TRIGGERS [FROM schema_name]; //我測試后面添加數(shù)據(jù)庫名字刪除失敗
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name

  • 觸發(fā)器的執(zhí)行順序

我們建立的數(shù)據(jù)庫一般都是 InnoDB 數(shù)據(jù)庫,其上建立的表是事務(wù)性表,也就是事務(wù)安全的。這時(shí),若SQL語句或觸發(fā)器執(zhí)行失敗,MySQL 會(huì)回滾事務(wù),有:
①如果 BEFORE 觸發(fā)器執(zhí)行失敗,SQL 無法正確執(zhí)行。
②SQL 執(zhí)行失敗時(shí),AFTER 型觸發(fā)器不會(huì)觸發(fā)。
③AFTER 類型的觸發(fā)器執(zhí)行失敗,SQL 會(huì)回滾。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容