觸發器—trigeer是數據庫下用於監視數據改變的某種情況,並觸發執行某種操作的一個功能,簡單來說就是對某一張表符合某種條件的更改前或者後執行一段存儲過程。在這裏就簡單的說一說在MySQL下如何使用觸發器。在使用MySQL的觸發器可以檢查數據完整性、可以捕獲數據庫層中業務邏輯中的錯誤、對於有使用審計表中數據的更改非常有用,但是它的缺點是在使用會觸發器後只能提供擴展驗證,並且無法替換所有驗證,其次增加了後期維護成本,最後是在目前MySQL下觸發器對服務器的開銷增加比較大,建議在業務比較頻繁的表中不要使用大量的觸發器,在MySQL中觸發器創建語法四要素:1.監視對象(大多都是對錶) 2.監視事件(insert/update/delete) 3.觸發時間(after/before) 4.觸發事件(insert/update/delete)。
首先,目前的MySQL中在使用觸發器時能對某一張表進行insert、delete、update操作的前或者是後爲條件從而觸發事先定義好的操作。這裏需要注意的是在使用MySQL的觸發器時必須要有足夠大的權限至少需要用super用戶的權限,在缺省條件下MySQL的觸發器同function一樣普通用戶是無法進行操作的,如果需要賦予普通用戶創建觸發器的權限需要在開啓log_bin_trust_function_creators變量:
mysql> SET GLOBAL log_bin_trust_function_creators = ON;#在配置好後在my.cnf或my.ini中添加 Query OK, 0 rows affected (0.00 sec)
在該參數開啓後普通用戶就也可以創建觸發器和function,其次目前的MySQL中觸發器僅支持DML並不支持DDL,其創建常用DDL語法如下:
CREATE TRIGGER 觸發器名 AFTER/BEFORE INSERT/UPDATE/DELETE ON 表名 FOR EACH ROW #這句話在MYSQL是固定的 BEGIN DML語句; END;
此外還要注意在MySQL的觸發器下的old於new的區別,以下引用網絡上一段圖文:
1、當使用insert語句的時候,如果原表中沒有數據的話,那麼對於插入數據後表來說新插入的那條數據就是new
2、當使用delete語句的時候,刪除的那一條數據相對於刪除數據後表的數據來說就是old
3、當使用update語句的時候,當修改原表數據的時候相對於修改數據後表的數據來說原表中修改的那條數據就是old,而修改數據後表被修改的那條數據就是new
所以在觸發器中使用new和old還是有區別的,在這裏用2張表說明下,有2張表tbl_name和tbl_name_log
tbl_name的DDL:
DROP TABLE IF EXISTS `tbl_name`; CREATE TABLE `tbl_name` ( `id` int(10) NOT NULL COMMENT '姓名ID', `name` varchar(50) NOT NULL COMMENT '姓名', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
tbl_name_log的DDL:
DROP TABLE IF EXISTS `tbl_name_log`; CREATE TABLE `tbl_name_log` ( `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '審計ID', `action` varchar(10) NOT NULL COMMENT 'tbl_name表中執行的操作', `name` varchar(50) NOT NULL COMMENT '操作的姓名', `time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '操作時間', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
在tbl_name中分別對insert/update/delete三種事件後做出記錄於tbl_name_log表中,就可以在tbl_name添加3個觸發器:
DROP TRIGGER IF EXISTS `audit_name_add`; DELIMITER ;; CREATE TRIGGER `audit_name_add` AFTER INSERT ON `tbl_name` FOR EACH ROW #在tbl_name插入後在tbl_name_log記錄日誌的觸發器 BEGIN INSERT INTO `tbl_name_log` (`action`,`name`,`time`) VALUES ('add',new.`name`,NOW()); END ;; DELIMITER ; DROP TRIGGER IF EXISTS `audit_name_update`; DELIMITER ;; CREATE TRIGGER `audit_name_update` AFTER UPDATE ON `tbl_name` FOR EACH ROW #在tbl_name更新後在tbl_name_log記錄日誌的觸發器 BEGIN INSERT INTO `tbl_name_log` (`action`,`name`,`time`) VALUES ('update',new.`name`,NOW()); END ;; DELIMITER ; DROP TRIGGER IF EXISTS `audit_name_del`; DELIMITER ;; CREATE TRIGGER `audit_name_del` AFTER DELETE ON `tbl_name` FOR EACH ROW #在tbl_name刪除後在tbl_name_log記錄日誌的觸發器 BEGIN INSERT INTO `tbl_name_log` (`action`,`name`,`time`) VALUES ('del',old.`name`,NOW()); END ;; DELIMITER ;
測試一下,在tbl_name表進行插入、更新、刪除後都會有相應的記錄於tbl_name_log表中