柚子快報(bào)邀請(qǐng)碼778899分享:mysql 觸發(fā)器
柚子快報(bào)邀請(qǐng)碼778899分享:mysql 觸發(fā)器
? ? ? ? 學(xué)習(xí)了mysql 視圖,接著學(xué)習(xí)觸發(fā)器
1,創(chuàng)建觸發(fā)器
????????觸發(fā)器(trigger)是個(gè)特殊的存儲(chǔ)過程,不同的是,執(zhí)行存儲(chǔ)過程要使用CALL語句來調(diào)用,而觸發(fā)器的執(zhí)行不需要使用CALL語句來調(diào)用,也不需要手工啟動(dòng),只要當(dāng)一個(gè)預(yù)定義的事件發(fā)生的時(shí)候,就會(huì)被MySQL自動(dòng)調(diào)用。比如當(dāng)對(duì)fruits 表進(jìn)行操作(INSERT、DELETE或UPDATE)時(shí)就會(huì)激活它執(zhí)行。
????????觸發(fā)器可以查詢其他表,而且可以包含復(fù)雜的SQL語句。它們主要用于滿足復(fù)雜的業(yè)務(wù)規(guī)則或要求。例如:可以根據(jù)客戶當(dāng)前的賬戶狀態(tài),控制是否允許插入新訂單。本節(jié)將介紹如何創(chuàng)建觸發(fā)器。
1,創(chuàng)建只有一個(gè)執(zhí)行語句的觸發(fā)器
????????創(chuàng)建一個(gè)觸發(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ā)器執(zhí)行語句。
????????【例1】創(chuàng)建一個(gè)單執(zhí)行語句的觸發(fā)器,代碼如下:
CREATE TABLE account (acct_num INT,amount DECIMAL (10,2));
CREATE TRIGGER ins_sum BEFORE INSERT ON account
FOR EACH ROW SET @sum = @sum + NEW.amount;
????????首先創(chuàng)建一個(gè)account表,表中有兩個(gè)字段,分別為: acct_num字段(定義為int類型),amount字段(定義成浮點(diǎn)類型)﹔其次創(chuàng)建一個(gè)名為 ins_sum的觸發(fā)器,觸發(fā)的條件是向數(shù)據(jù)表account插入數(shù)據(jù)之前,對(duì)新插入的amount字段值進(jìn)行求和計(jì)算。
????????代碼執(zhí)行如下:
SET @sum=0;
INSERT INTO account VALUES(1,1.00),(2,2.00) ;
SELECT @sum;
????????首先創(chuàng)建一個(gè)account表,在向表account插入數(shù)據(jù)之前,計(jì)算所有新插入的account 表的amount值之和,觸發(fā)器的名稱為ins_sum,條件是在向表插入數(shù)據(jù)之前觸發(fā)。
2,創(chuàng)建有多個(gè)執(zhí)行語句的觸發(fā)器
????????創(chuàng)建多個(gè)執(zhí)行語句的觸發(fā)器的語法如下:
CREATE TRIGGER trigger_name trigger_time trigger_event
ON tbl name FOR EACH ROW
BEGIN
語句執(zhí)行列表
END
????????其中 trigger_name標(biāo)識(shí)觸發(fā)器的名稱,用戶自行指定;trigger_time標(biāo)識(shí)觸發(fā)時(shí)機(jī),可以指定為before或after;rigger_event標(biāo)識(shí)觸發(fā)事件,包括INSERT、UPDATE 和 DELETE;tbl_name標(biāo)識(shí)建立觸發(fā)器的表名,即在哪張表上建立觸發(fā)器;觸發(fā)器程序可以使用BEGIN和END作為開始和結(jié)束,中間包含多條語句。
?關(guān)鍵字:?
????????:NEW 和:OLD使用方法和意義,new 只出現(xiàn)在insert和update時(shí),old只出現(xiàn)在update和delete時(shí)。在insert時(shí)new表示新插入的行數(shù)據(jù),update時(shí)new表示要替換的新數(shù)據(jù)、old表示要被更改的原來的數(shù)據(jù)行,delete時(shí)old表示要被刪除的數(shù)據(jù)。?
????????【例2】創(chuàng)建一個(gè)包含多個(gè)執(zhí)行語句的觸發(fā)器,代碼如下:
CREATE TABLE test1(a1 INT);
CREATE TABLE test2(a2 INT);
CREATE TABLE test3(a3 INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE test4(
a4 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
b4 INT DEFAULT 0
);
DELIMITER //
CREATE TRIGGER testref BEFORE INSERT ON test1 FOR EACH ROW
BEGIN
INSERT INTO test2 SET a2 = NEW.a1;
DELETE FROM test3 WHERE a3 = NEW.a1;
UPDATE test4 SET b4 = b4+1 WHERE a4 = NEW.a1;
END //
INSERT INTO test3(a3) VALUES
(NULL), (NULL), (NULL), (NULL), (NULL),
(NULL),(NULL), (NULL), (NULL), (NULL);
INSERT INTO test4(a4) VALUES
(0), (0),(0),(0), (0),
(0), (0),(0),(0), (0);
????????上面的代碼是創(chuàng)建了一個(gè)名為testref的觸發(fā)器,這個(gè)觸發(fā)器的觸發(fā)條件是在向表test1插入數(shù)據(jù)前執(zhí)行觸發(fā)器的語句,具體執(zhí)行的代碼如下:
INSERT INTO test1 VALUES
(1), (3), (1), (7), (1), (8),(4),(4);
那么4個(gè)表中的數(shù)據(jù)如下:
SELECT * FROM test1;
SELECT * FROM test2;
SELECT * FROM test3;
SELECT * FROM test4;
????????執(zhí)行結(jié)果顯示,在向表test1插入記錄的時(shí)候,test2、 test3、 test4 都發(fā)生了變化。從這個(gè)例子看INSERT觸發(fā)了觸發(fā)器,向test2中插入了test1 中的值,刪除了test3 中相同的內(nèi)容,?
????????同時(shí)更新了test4 中的b4,即與插入的值相同的個(gè)數(shù)。
2,查看觸發(fā)器
????????查看觸發(fā)器是指查看數(shù)據(jù)庫中已存在的觸發(fā)器的定義、狀態(tài)和語法信息等??梢酝ㄟ^命令
來查看已經(jīng)創(chuàng)建的觸發(fā)器。本節(jié)將介紹兩種查看觸發(fā)器的方法,分別是: SHOW TRIGGERS
和在triggers表中查看觸發(fā)器信息。
1,SHOW TRIGGERS語句查看觸發(fā)器信息
????????通過SHOW TRIGGERS查看觸發(fā)器的語句如下:
SHOW TRIGGERS;
????????[例3]通過SHOW TRIGGERS命令查看-一個(gè)觸發(fā)器,代碼如下: .
SHOW TRIGGERS;
????????創(chuàng)建一一個(gè)簡單的觸發(fā)器,名稱為trig. _update, 每次向account 表更新數(shù)據(jù)之后都會(huì)向名稱為myevent的數(shù)據(jù)表中插入-條記錄,數(shù)據(jù)表myevent定義如下:
CREATE TABLE myevent(
id int(11) DEFAULT NULL,
evt_name char (20) DEFAULT NULL
);
????????創(chuàng)建觸發(fā)器的執(zhí)行代碼如下:
CREATE TRIGGER trig_update AFTER UPDATE ON account
FOR EACH ROW INSERT INTO myevent VALUES (1, 'after update');
????????使用SHOW TRIGGERS命令查看觸發(fā)器:
SHOW TRIGGERS;
????????PS:如果用命令行,可以看到,信息顯示比較混亂。如果在SHOW TRIGGERS命令的后面添加上“\G’,顯示信息會(huì)比較有條理,執(zhí)行情況如下:
SHOW TRIGGERS \G
????????Trigger表示觸發(fā)器的名稱在這里兩個(gè)觸發(fā)器的名稱分別為ins_sum 和trig_update;Event
表示激活觸發(fā)器的事件這里的兩個(gè)觸發(fā)事件為插入操作INSERT和更新操作UPDATE; Table
表示激活觸發(fā)器的操作對(duì)象表,這里都為account表;Timing表示觸發(fā)器觸發(fā)的時(shí)間,分別為
插入操作之前(BEFORE)和更新操作之后(AFTER) ; Staterment 表示觸發(fā)器執(zhí)行的操作,
還有一些其他信息,比如SQL的模式、觸發(fā)器的定義賬戶和字符集等,這里不再一一介紹。
????????提示:SHOW TRIGGERS語句查看當(dāng)前創(chuàng)建的所有觸發(fā)器信息,在觸發(fā)器較少的情況下,使用該語句會(huì)很方便。如果要查看特定觸發(fā)器的信息,可以直接從information, schema 數(shù)據(jù)庫
中的tiggers表中查找。
2,在triggers表中查看觸發(fā)器信息
????????在MySQL中所有觸發(fā)器的定義都存在INFORMATION SCHEMA數(shù)據(jù)庫的TRIGGERS
表格中,可以通過查詢命令SELECT來查看,具體的語法如下:
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE condition;
????????[例4]通過SELECT命令查看觸發(fā)器,代碼如下:
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME= 'trig_update';
????????上述的命令是通過WHERE來指定查看特定名稱的觸發(fā)器,下面是指定觸發(fā)器名稱的執(zhí)行情況:
????????從上面的執(zhí)行結(jié)果可以得到:TRIGGERSCHEMA表示觸發(fā)器所在的數(shù)據(jù)庫;
????????TRIGGER_NAME后面是觸發(fā)器的名稱;EVENT_OBJECT__TABLE表示在哪個(gè)數(shù)據(jù)表上觸
發(fā)ACTION_STATEMENT 表示觸發(fā)器觸發(fā)的時(shí)候執(zhí)行的具體操作ACTION_ORIENTATION
是ROW,表示在每條記錄上都觸發(fā);ACTION__TIMING表示觸發(fā)的時(shí)刻是AFTER,剩下的
是和系統(tǒng)相關(guān)的信息。
????????也可以不指定觸發(fā)器名稱,這樣將查看所有的觸發(fā)器,命令如下:
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS;
這個(gè)命令會(huì)顯示這個(gè)TRIGGERS表中所有的觸發(fā)器信息。
3,觸發(fā)器的使用
????????觸發(fā)程序是與表有關(guān)的命名數(shù)據(jù)庫對(duì)象,當(dāng)表上出現(xiàn)特定事件時(shí),將激活該對(duì)象。在某些觸發(fā)程序的用法中,可用于檢查插入到表中的值,或?qū)Ω律婕暗闹颠M(jìn)行計(jì)算。
????????觸發(fā)程序與表相關(guān),當(dāng)對(duì)表執(zhí)行INSERT. DELETE 或UPDATE語句時(shí),將激活觸發(fā)程序。可以將觸發(fā)程序設(shè)置為在執(zhí)行語句之前或之后激活。例如,可以在從表中刪除每一行之前,或在更新每一行之后激活觸發(fā)程序。
????????[例5]創(chuàng)建一個(gè)在account表插入記錄之后,更新myevent數(shù)據(jù)表的觸發(fā)器,代碼如下:
CREATE TRIGGER trig_insert AFTER INSERT ON account
FOR EACH ROW INSERT INTO myevent VALUES (2, 'after insert');
????????上面的代碼創(chuàng)建了一個(gè)trig. _insert 的觸發(fā)器在向表account插入數(shù)據(jù)之后會(huì)向表myevent
????????插入一組數(shù)據(jù),代碼執(zhí)行如下:
INSERT INTO account VALUES (1, 1.00), (2, 2.00);
SELECT * FROM myevent;
????????從執(zhí)行的結(jié)果來看,是創(chuàng)建了一個(gè)名稱為trig_insert 的觸發(fā)器,它是在向account 插入記
錄之后進(jìn)行觸發(fā),執(zhí)行的操作是向表myevent 插入一條記錄。
4,刪除觸發(fā)器.
????????使用DROP TRIGGER語句可以刪除MySQL中已經(jīng)定義的觸發(fā)器,刪除觸發(fā)器語句基本
語法格式如下:
DROP TRIGGER [schema_name.] trigger_name
????????其中,schema_name表示數(shù)據(jù)庫名稱,是可選的。如果省略了schema,將從當(dāng)前數(shù)據(jù)庫中舍棄觸發(fā)程序: trigger_name 是要?jiǎng)h除的觸發(fā)器的名稱。
????????[例6]刪除-一個(gè)觸發(fā)器,代碼如下:
DROP TRIGGER test.trig_insert;
????????上面的代碼中test是觸發(fā)器所在的數(shù)據(jù)庫,trig_insert是一個(gè)觸發(fā)器的名稱。代碼執(zhí)行如下:
觸發(fā)器trig_insert刪除成功。
5,疑問解答
疑問1 :使用觸發(fā)器時(shí)須特別注意。
????????在使用觸發(fā)器的時(shí)候需要注意,對(duì)于相同的表,相同的事件只能創(chuàng)建一一個(gè)觸發(fā)器,比如對(duì)
表account創(chuàng)建了一個(gè)BEFOREINSERT觸發(fā)器,那么如果對(duì)表account再次創(chuàng)建一個(gè)BEFORE
INSERT觸發(fā)器,MySQL將會(huì)報(bào)錯(cuò),此時(shí),只可以在表account.上創(chuàng)建AFTER INSERT或者
BEFOREUPDATE類型的觸發(fā)器。靈活地運(yùn)用觸發(fā)器將為操作省去很多麻煩。
疑問2 :及時(shí)刪除不再需要的觸發(fā)器。
????????觸發(fā)器定義之后,每次執(zhí)行觸發(fā)事件,都會(huì)激活觸發(fā)器并執(zhí)行觸發(fā)器中的語句。如果需求
發(fā)生變化,而觸發(fā)器沒有進(jìn)行相應(yīng)的改變或者刪除,則觸發(fā)器仍然會(huì)執(zhí)行舊的語句,從而會(huì)影
響新的數(shù)據(jù)的完整性。因此,要將不再使用的觸發(fā)器及時(shí)刪除。
總結(jié):
? ? ? ? 看起來觸發(fā)器挺好用的,但實(shí)際的話,感覺觸發(fā)器基本沒用,要處理也基本是代碼去處理相應(yīng)的邏輯,這樣也更好維護(hù)。
? ? ? ? 上一篇: 《mysql 視圖》
? ? ? ? 下一篇: 《mysql 性能優(yōu)化》
柚子快報(bào)邀請(qǐng)碼778899分享:mysql 觸發(fā)器
精彩內(nèi)容
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。