MySQL数据库:触发器Trigger
?
一、什么是觸發(fā)器:
觸發(fā)器是與表有關(guān)的數(shù)據(jù)庫對象,當觸發(fā)器所在表上出現(xiàn)指定事件并滿足定義條件的時候,將執(zhí)行觸發(fā)器中定義的語句集合。觸發(fā)器的這種特性可以協(xié)助應(yīng)用在數(shù)據(jù)庫端確保數(shù)據(jù)的完整性。觸發(fā)器是一個特殊的存儲過程,不同的是存儲過程要用call來調(diào)用,而觸發(fā)器不需要使用call,也不需要手工調(diào)用,它在插入,刪除或修改特定表中的數(shù)據(jù)時觸發(fā)執(zhí)行,它比數(shù)據(jù)庫本身標準的功能有更精細和更復(fù)雜的數(shù)據(jù)控制能力。
?
二、創(chuàng)建觸發(fā)器:
1、語法:
CREATE TRIGGER trigger_name
trigger_time
trigger_event ON tbl_name
FOR EACH ROW
trigger_stmt
?
其中:
trigger_name:標識觸發(fā)器名稱,用戶自行指定;
trigger_time:標識觸發(fā)時機,取值為 BEFORE 或 AFTER;
trigger_event:標識觸發(fā)事件,取值為 INSERT、UPDATE 或 DELETE;
tbl_name:標識建立觸發(fā)器的表名,即在哪張表上建立觸發(fā)器;
trigger_stmt:觸發(fā)器程序體,可以是一句SQL語句,或者用 BEGIN 和 END 包含的多條語句。
由此可見,可以建立6種觸發(fā)器,即:BEFORE INSERT、BEFORE UPDATE、BEFORE DELETE、AFTER INSERT、AFTER UPDATE、AFTER DELETE。另外有一個限制是不能同時在一個表上建立2個相同類型的觸發(fā)器,因此在一個表上最多建立6個觸發(fā)器。
2、Trigger_event?詳解:
MySQL 除了對 INSERT、UPDATE、DELETE 基本操作進行定義外,還定義了 LOAD DATA 和 REPLACE 語句,這兩種語句也能引起上述6中類型的觸發(fā)器的觸發(fā)。
(1)LOAD DATA 語句用于將一個文件裝入到一個數(shù)據(jù)表中,相當與一系列的 INSERT 操作。
(2)REPLACE 語句一般來說和 INSERT 語句很像,只是在表中有 primary key 或 unique 索引時,如果插入的數(shù)據(jù)和原來 primary key 或 unique 索引一致時,會先刪除原來的數(shù)據(jù),然后增加一條新數(shù)據(jù),也就是說,一條 REPLACE 語句有時候等價于一條。
(3)UPDATE?語句,有時候等價于一條 DELETE 語句加上一條 INSERT 語句。
INSERT 型觸發(fā)器:插入某一行時激活觸發(fā)器,可能通過 INSERT、LOAD DATA、REPLACE 語句觸發(fā);
UPDATE 型觸發(fā)器:更改某一行時激活觸發(fā)器,可能通過 UPDATE 語句觸發(fā);
DELETE 型觸發(fā)器:刪除某一行時激活觸發(fā)器,可能通過 DELETE、REPLACE 語句觸發(fā)。
3、BEGIN … END?詳解:
在MySQL中,BEGIN … END 語句的語法為:
BEGIN
[statement_list]
END
其中,statement_list 代表一個或多個語句的列表,列表內(nèi)的每條語句都必須用分號(;)來結(jié)尾。
而在MySQL中,分號是語句結(jié)束的標識符,遇到分號表示該段語句已經(jīng)結(jié)束,MySQL可以開始執(zhí)行了。因此,解釋器遇到statement_list 中的分號后就開始執(zhí)行,然后會報出錯誤,因為沒有找到和 BEGIN 匹配的 END。
這時就會用到 DELIMITER 命令,它是一條命令,不需要語句結(jié)束標識,語法為:
DELIMITER new_delemiter
new_delemiter 可以設(shè)為1個或多個長度的符號,默認的是分號(;),我們可以把它修改為其他符號,如$:
DELIMITER $
在這之后的語句,以分號結(jié)束,解釋器不會有什么反應(yīng),只有遇到了$,才認為是語句結(jié)束。注意,使用完之后,我們還應(yīng)該記得把它給修改回來。
4、觸發(fā)器示例:
假設(shè)系統(tǒng)中有兩個表:
班級表 class(班級號 classID, 班內(nèi)學生數(shù) stuCount)
學生表 student(學號 stuID, 所屬班級號 classID)
要創(chuàng)建觸發(fā)器來使班級表中的班內(nèi)學生數(shù)隨著學生的添加自動更新,代碼如下:
DELIMITER $
create trigger tri_stuInsert after insert
on student for each row
begin
declare c int;
set c = (select stuCount from class where classID=new.classID);
update class set stuCount = c + 1 where classID = new.classID;
end$
DELIMITER ;
5、NEW?與 OLD 詳解:
(1)在 INSERT 型觸發(fā)器中,NEW 用來表示將要(BEFORE)或已經(jīng)(AFTER)插入的新數(shù)據(jù);
(2)在 UPDATE 型觸發(fā)器中,OLD 用來表示將要或已經(jīng)被修改的原數(shù)據(jù),NEW 用來表示將要或已經(jīng)修改為的新數(shù)據(jù);
(3)在 DELETE 型觸發(fā)器中,OLD 用來表示將要或已經(jīng)被刪除的原數(shù)據(jù);
使用方法: NEW.columnName (columnName 為相應(yīng)數(shù)據(jù)表某一列名)
另外,OLD 是只讀的,而 NEW 則可以在觸發(fā)器中使用 SET 賦值,這樣不會再次觸發(fā)觸發(fā)器,造成循環(huán)調(diào)用(如每插入一個學生前,都在其學號前加“2013”)。
?
三、觸發(fā)器其他操作:
1、查看觸發(fā)器信息:
查看觸發(fā)器是指數(shù)據(jù)庫中已存在的觸發(fā)器的定義、狀態(tài)、語法信息等。
SHOW TRIGGERS [FROM schema_name];? ? --第一種
其中,schema_name 可以指定數(shù)據(jù)庫名。
在TRIGGERS 表中查看觸發(fā)器信息:
SELECT * FROM `information_schema`.`TRIGGERS` WHERE `TRIGGER_NAME`='xxxx';? ? ?--第二種
2、刪除觸發(fā)器
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name;
?
四、觸發(fā)器相關(guān):
1、觸發(fā)器的執(zhí)行順序與異常機制:
MySQL的觸發(fā)器是按照BEFORE觸發(fā)器、行操作、AFTER觸發(fā)器的順序執(zhí)行的,其中任何一步發(fā)生錯誤都不會繼續(xù)執(zhí)行剩下的操作。如果是對事務(wù)表進行的操作,那么會整個作為一個事務(wù)被回滾,但是如果是對非事務(wù)表進行的操作,那么已經(jīng)更新的記錄將無法回滾。
(1)如果 BEFORE 觸發(fā)器執(zhí)行失敗,SQL 無法正確執(zhí)行;
(2)SQL 執(zhí)行失敗時,AFTER 型觸發(fā)器不會觸發(fā);
(3)AFTER 類型的觸發(fā)器執(zhí)行失敗,SQL 會回滾。
2、觸發(fā)器的使用限制:
(1)觸發(fā)器只能創(chuàng)建在永久表上,不能對臨時表創(chuàng)建觸發(fā)器;
(2)觸發(fā)程序不能調(diào)用將數(shù)據(jù)返回給客戶端的存儲程序,也不能使用CALL語句的動態(tài)SQL語句,但是允許存儲過程或者函數(shù)通過OUT或者INOUT類型的參數(shù)將數(shù)據(jù)返回觸發(fā)器是可以的,但是不能調(diào)用直接返回數(shù)據(jù)的過程。
(3)觸發(fā)器中不能使用開啟或結(jié)束事務(wù)的語句段,比如,開始事務(wù)(START TRANSACTION)、提交事務(wù)(COMMIT)或是回滾事務(wù)(ROLLBACK),但是回滾到一個保存點(SAVEPOINT是允許的,因為回滾到保存點不會結(jié)束事務(wù));
(4)外鍵不會激活觸發(fā)器;
(5)當使用基于行的復(fù)制時,從表上的觸發(fā)器不會因操作主表中的數(shù)據(jù)而激活。當使用基于語句的復(fù)制時,從表上的觸發(fā)器會被激活。
(6)觸發(fā)器中不允許返回值,因此觸發(fā)器中不能有返回語句,如果要立即停止一個觸發(fā)器,應(yīng)該使用LEAVE語句;
3、觸發(fā)器的作用:
(1)安全性。可以基于數(shù)據(jù)庫的值使用戶具有操作數(shù)據(jù)庫的某種權(quán)利。
--可以基于時間限制用戶的操作,例如不允許下班后和節(jié)假日修改數(shù)據(jù)庫數(shù)據(jù)。
--可以基于數(shù)據(jù)庫中的數(shù)據(jù)限制用戶的操作,例如不允許股票的價格的升幅一次超過10%。
(2)審計。可以跟蹤用戶對數(shù)據(jù)庫的操作。???
--審計用戶操作數(shù)據(jù)庫的語句。
--把用戶對數(shù)據(jù)庫的更新寫入審計表。
(3)實現(xiàn)復(fù)雜的數(shù)據(jù)完整性規(guī)則:
--實現(xiàn)非標準的數(shù)據(jù)完整性檢查和約束。觸發(fā)器可產(chǎn)生比規(guī)則更為復(fù)雜的限制。與規(guī)則不同,觸發(fā)器可以引用列或數(shù)據(jù)庫對象。例如,觸發(fā)器可回退任何企圖吃進超過自己保證金的期貨。
--提供可變的缺省值。
(4)實現(xiàn)復(fù)雜的非標準的數(shù)據(jù)庫相關(guān)完整性規(guī)則。觸發(fā)器可以對數(shù)據(jù)庫中相關(guān)的表進行連環(huán)更新。例如,在auths表author_code列上的刪除觸發(fā)器可導致相應(yīng)刪除在其它表中的與之匹配的行。
--修改或刪除時級聯(lián)修改或刪除其它表中的與之匹配的行。
--在修改或刪除時把其它表中的與之匹配的行設(shè)成NULL值。
--在修改或刪除時把其它表中的與之匹配的行級聯(lián)設(shè)成缺省值。
--觸發(fā)器能夠拒絕或回退那些破壞相關(guān)完整性的變化,取消試圖進行數(shù)據(jù)更新的事務(wù)。當插入一個與其主健不匹配的外部鍵時,這種觸發(fā)器會起作用。例如,可以在books.author_code?列上生成一個插入觸發(fā)器,如果新值與auths.author_code列中的某值不匹配時,插入被回退。
(5)同步實時地復(fù)制表中的數(shù)據(jù)。
(6)自動計算數(shù)據(jù)值,如果數(shù)據(jù)的值達到了一定的要求,則進行特定的處理。例如,如果公司的帳號上的資金低于5萬元則立即給財務(wù)人員發(fā)送警告數(shù)據(jù)。
?
?
相關(guān)博客:https://www.cnblogs.com/duodushu/p/5446384.html
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的MySQL数据库:触发器Trigger的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL数据库:视图View
- 下一篇: MySQL数据库:游标Cursor