新聞中心
觸發(fā)器(trigger):監(jiān)視某種情況,并觸發(fā)某種操作,它是提供給程序員和數(shù)據(jù)分析員來保證數(shù)據(jù)完整性的一種方法,它是與表事件相關的特殊的存儲過程,它的執(zhí)行不是由程序調(diào)用,也不是手工啟動,而是由事件來觸發(fā),例如當對一個表進行操作( insert,delete, update)時就會激活它執(zhí)行。觸發(fā)器經(jīng)常用于加強數(shù)據(jù)的完整性約束和業(yè)務規(guī)則等。

網(wǎng)站建設哪家好,找成都創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設計、網(wǎng)站建設、微信開發(fā)、成都微信小程序、集團企業(yè)網(wǎng)站建設等服務項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了愛民免費建站歡迎大家使用!
基本理解:
\1. 使用場合:
觸發(fā)器是基于事件的,主要的事件也就是MySQL的增刪改操作,即insert,delete,update。
\2. 觸發(fā)器的命名
Trigger names exist in the schema namespace, meaning that all triggers must have unique names within a schema. Triggers in different schemas can have the same name.
因為觸發(fā)器在單表的命名空間內(nèi),所以同一個表的觸發(fā)器名稱需要不同。不同表可以有相同的觸發(fā)器名稱。
\3. 觸發(fā)器執(zhí)行順序
如果有相同的update(或者delete,insert)觸發(fā)器,就會按照創(chuàng)建的時間來執(zhí)行。
而FOLLOWS 和 PRECEDES 可以修改trigger的執(zhí)行順序
例如官方的案例:
mysql> CREATE TRIGGER ins_transaction BEFORE INSERT ON account
FOR EACH ROW PRECEDES ins_sum
SET
@deposits = @deposits + IF(NEW.amount>0,NEW.amount,0),
@withdrawals = @withdrawals + IF(NEW.amount
Query OK, 0 rows affected (0.01 sec)
ins_transaction和ins_sum分別是兩個觸發(fā)器的名稱。
4. 觸發(fā)器的作用:
\1. 安全性??梢曰跀?shù)據(jù)庫的值使用戶具有操作數(shù)據(jù)庫的某種權利。
1)可以基于時間限制用戶的操作,例如不允許下班后和節(jié)假日修改數(shù)據(jù)庫數(shù)據(jù)。
2)可以基于數(shù)據(jù)庫中的數(shù)據(jù)限制用戶的操作,例如不允許單個商品的購買量大于一個固定值。
\2. 審計??梢愿櫽脩魧?shù)據(jù)庫的操作。
1)審計用戶操作數(shù)據(jù)庫的語句。
2)把用戶對數(shù)據(jù)庫的更新寫入審計表。
這一塊因為本人沒有用過,就不贅述了,以后有機會來補充
\3. 實現(xiàn)復雜的數(shù)據(jù)完整性規(guī)則
實現(xiàn)非標準的數(shù)據(jù)完整性檢查和約束。觸發(fā)器可產(chǎn)生比規(guī)則更為復雜的限制。與規(guī)則不同,觸發(fā)器可以引用列或數(shù)據(jù)庫對象。例如,觸發(fā)器可回退任何企圖吃進超過自己保證金的期貨。
\4. 實現(xiàn)復雜的非標準的數(shù)據(jù)庫相關完整性規(guī)則。
1)觸發(fā)器可以對數(shù)據(jù)庫中相關的表進行連環(huán)更新。這是用得比較多的一種實現(xiàn)功能。
2) 觸發(fā)器能夠拒絕或回退那些破壞相關完整性的變化,取消試圖進行數(shù)據(jù)更新的事務。當插入一個與其主健不匹配的外部鍵時,這種觸發(fā)器會起作用。
下面的例子我會比較詳細的描述這兩個特性。
\5. 同步實時地復制表中的數(shù)據(jù)。
\6. 自動計算數(shù)據(jù)值,如果數(shù)據(jù)的值達到了一定的要求,則進行特定的處理。
例如,如果公司的帳號上的資金低于5萬元則立即給財務人員發(fā)送警告數(shù)據(jù)。
**(**1)插入數(shù)據(jù):
當用戶添加一個訂單的時候,我們需要對商品表格中的庫存(storage)進行相應的改動
mysql> create trigger shop_goods
-> after insert on shoppingcar
-> for each row
-> update goods set storage=storage-new.amount where id=new.g_id
-> ;
Query OK, 0 rows affected (0.03 sec)
mysql>insert into shoppingcar values(1,1,2);
查詢結果:
goods表
+-------+---------+-------------+---------+
| id | gname | description | storage |
+-------+---------+---------- --+---------+
| 1 | huawei | rongyao9 | 198 |
| 2 | iphone | iphoneX | 100 |
+-------+---------+-------------+---------+
shoppingcar表
+----- -+----- -+--------+
| u_id | g_id | amount |
+-------+-------+--------+
| 1 | 1 | 2 |
+-------+-------+--------+
**關于**new和old的使用
new表示新的數(shù)據(jù)行,而old表示舊的數(shù)據(jù)行
**(**2)刪除數(shù)據(jù)
例如,用戶撤銷一個訂單的時候,我們需要將商品的數(shù)量加回去
mysql> create trigger shop_good1
-> after delete on shoppingcar
-> for each row
-> update goods set storage=storage+old.amount where id=old.g_id;
Query OK, 0 rows affected (0.01 sec)
刪除前:
mysql> select * from goods;
+-----+---------+-------------+---------+
| id | gname | description | storage |
+-----+---------+-------------+---------+
| 1 | huawei | rongyao9 | 198 |
| 2 | iphone | iphoneX | 100 |
+-----+---------+-------------+---------+
2 rows in set (0.00 sec)
mysql> select * from shoppingcar;
+------+------+--------+
| u_id | g_id | amount |
+------+------+--------+
| 1 | 1 | 2 |
+------+------+--------+
1 rows in set (0.00 sec)
刪除數(shù)據(jù):
mysql> delete from shoppingcar where g_id=1;
Query OK, 1 row affected (0.03 sec)
結果:
**(**3)更新數(shù)據(jù)(可增可減)
當用戶對想通過修改購物車的數(shù)量來修改自己購買某種商品的數(shù)量,那么,我們的庫存也需要跟著改動。
mysql> create trigger shop_good2
-> after update on shoppingcar
-> for each row
-> update goods set storage=storage-new.amount+old.amount where id=new.g_id/old.g_id;
Query OK, 0 rows affected (0.14 sec)
查看觸發(fā)器命令
show triggers
這個命令只能看到都有哪些的triggers,而看不到trigger的具體信息。
所有觸發(fā)器信息都存儲在information_schema數(shù)據(jù)庫下的triggers表中,可以使用SELECT語句查詢。如果有很多個觸發(fā)器,最好通過TRIGGER_NAME字段指定查詢某一個觸發(fā)器。
例如:
SELECT * FROM information_schema.triggers WHERE TRIGGER_NAME=’XXX’;
(4)限制條件
條件限制對一些涉及到金額的場合(如開篇提到的)非常重要,在電商的限購數(shù)額中也會有應用。
trigger利用delimiter,begin和if語句塊實現(xiàn)限制條件。
例如:
mysql> delimiter //
mysql> create trigger shop_limit before update on shoppingcar
-> for each row
-> begin
-> if new.amount>3 then
-> set new.amount=3;
-> elseif new.amountthen
-> set new.amount=0;
-> end if;
-> end; //
mysql> delimiter ;
條件語句程序塊用begin和end包裹起來實現(xiàn)
delimiter:切換結束符,因為;是MySQL中默認的結束符,如果程序塊中出現(xiàn);符號,就會引起沖突。最后要將結束符修改回來。注意delimiter與結束符之間有空格,否則會無法切換。
更新數(shù)據(jù)前:
更新數(shù)據(jù):
mysql> update shoppingcar set amount=4 where u_id=1;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
更新數(shù)據(jù)后:
購買量無法超過3
關于觸發(fā)器與事務
對于事務表(Innodb),before語句后面的判斷語句失敗將會導致回滾事件語句執(zhí)行的所有更改。觸發(fā)器失敗會導致語句失敗,因此觸發(fā)器失敗也會導致回滾。對于非事務性表(MyISAM),無法執(zhí)行此類回滾,因此盡管語句失敗,但在錯誤點之前執(zhí)行的任何更改仍然有效。
關于觸發(fā)器的使用限制
觸發(fā)器執(zhí)有一些限制:
\1. 觸發(fā)器不能使用CALL 語句來將數(shù)據(jù)返回給客戶端或使用動態(tài)SQL的存儲過程。但允許存儲過程通過OUT或INOUT 參數(shù)將數(shù)據(jù)返回到觸發(fā)器 。
\2. 觸發(fā)不能使用事務相關的語句,如 START TRANSACTION,COMMIT或ROLLBACK。因為觸發(fā)器對update,delete,insert等事件做了處理,并且是按照before,SQL語句,after的順序來執(zhí)行的,一旦某一步出錯,就會回滾數(shù)據(jù)。如果在觸發(fā)器中使用事務,就會產(chǎn)生矛盾。
新聞名稱:MySQL觸發(fā)器深入講解
分享鏈接:http://www.5511xx.com/article/dpcgpeh.html


咨詢
建站咨詢
