《MySQL之觸發器》要點:
本文介紹了MySQL之觸發器,希望對您有用。如果有疑問,可以聯系我們。
MySQL從5.0.2版本開始支持觸發器的功能,本次博客就來介紹一下觸發器,mysql版本:mysql-5.7.19.
什么是觸發器
觸發器是與表有關的數據庫對象,在滿足定義條件時觸發,并執行觸發器中定義的語句集合.觸發器的這種特性可以幫忙應用在數據庫端確保數據的完整性.
舉個例子,比如你現在有兩個表【用戶表】和【日志表】,當一個用戶被創建的時候,就需要在日志表中插入創建的log日志,如果在不使用觸發器的情況下,你需要使用兩條插入語句才能實現,但是如果你定義了一個觸發器,觸發器的作用就是當你在用戶表中插入一條數據的之后幫你在日志表中插入一條日志信息.
當然觸發器并不是只能進行插入操作,還能執行修改,刪除.
創建觸發器
創建觸發器的語法如下:
CREATE TRIGGER trigger_name trigger_time trigger_event ON tb_name FOR EACH ROW trigger_stmttrigger_name:觸發器的名稱tirgger_time:觸發時機,為BEFORE或者AFTERtrigger_event:觸發事件,為INSERT、DELETE或者UPDATEtb_name:表示建立觸發器的表明,就是在哪張表上建立觸發器trigger_stmt:觸發器的程序體,可以是一條SQL語句或者是用BEGIN和END包括的多條語句所以可以說MySQL創建以下六種觸發器:BEFORE INSERT,BEFORE DELETE,BEFORE UPDATEAFTER INSERT,AFTER DELETE,AFTER UPDATE
tigger_event:
load data語句是將文件的內容插入到表中,相當于是insert語句,而replace語句在一般的情況下和insert差不多,但是如果表中存在primary 或者unique索引的時候,如果插入的數據和本來的primary key或者unique相同的時候,會刪除本來的數據,然后增加一條新的數據,所以有的時候執行一條replace語句相當于執行了一條delete和insert語句.
trigger_stmt:
trigger_stmt可以是一條SQL語句,也可以是多條SQL代碼塊,那如何創建呢?
DELIMITER $ #將語句的分隔符改為$BEGINsql1;sql2;...sqlnEND $DELIMITER ; #將語句的分隔符改回本來的分號";"
在BEGIN...END語句中也可以定義變量,但是只能在BEGIN...END內部使用:
DECLARE var_name var_type [DEFAULT value] #定義變量,可指定默認值SET var_name = value #給變量賦值
NEW和OLD的使用:
根據以上的表格,可以使用一下格式來使用相應的數據:
NEW.columnname:新增行的某列數據OLD.columnname:刪除行的某列數據
說了這么多現在我們來創建一個觸發器吧!
現在有表如下:
mysql> desc userinfo;+----------+-------------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+----------+-------------+------+-----+---------+----------------+| id | int(11) | NO | PRI | NULL | auto_increment || username | varchar(20) | YES | | NULL | || passwd | varchar(20) | YES | | NULL | |+----------+-------------+------+-----+---------+----------------+3 rows in set (0.00 sec)mysql> desc log;+-------+--------------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+-------+--------------+------+-----+---------+----------------+| id | int(11) | NO | PRI | NULL | auto_increment || log | varchar(100) | YES | | NULL | |+-------+--------------+------+-----+---------+----------------+2 rows in set (0.00 sec)
需求是:當在userinfo中插入一條數據,就會在log中生成一條日志信息.
創建觸發器:
DELIMITER $CREATE TRIGGER user_log AFTER INSERT ON userinfo FOR EACH ROWBEGINDECLARE s1 VARCHAR(40);DECLARE s2 VARCHAR(20);SET s2 = " is created";SET s1 = CONCAT(NEW.username,s2); #函數CONCAT可以將字符串連接INSERT INTO log(log) values(s1);END $DELIMITER ;
在userinfo中插入數據并查看數據:
mysql> insert into userinfo(username,passwd) values('frank','123');Query OK, 1 row affected (0.01 sec)mysql> select * from userinfo;+----+----------+--------+| id | username | passwd |+----+----------+--------+| 1 | frank | 123 |+----+----------+--------+1 row in set (0.00 sec)
好的,我們再來查看一下log表吧!
mysql> select * from log;+----+------------------+| id | log |+----+------------------+| 1 | frank is created |+----+------------------+1 row in set (0.00 sec)
通過上面的例子,可以看到只需要在userinfo中插入用戶的信息,日志會自動記錄到log表中,這也許就是觸發器給我帶來的便捷吧!
刪除觸發器
一次可以刪除一個觸發器,語法如下:
DROP TRIGGER [db_name.]trigger_name #如果不指定db_name,默認為當前的數據庫.
比如刪除上面例子的觸發器:
mysql> drop trigger user_log;Query OK, 0 rows affected (0.00 sec)
查看觸發器
可以通過show triggers命令查看觸發器的狀態:
mysql> show triggers \G;*************************** 1. row ***************************Trigger: user_log Event: INSERTTable: userinfo Statement: BEGINDECLARE s1 VARCHAR(40);DECLARE s2 VARCHAR(20);SET s2 = " is created"; SET s1 = CONCAT(NEW.username,s2);INSERT INTO log(log) values(s1);END Timing: AFTER Created: 2017-09-22 21:12:46.02 sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION Definer: root@localhostcharacter_set_client: utf8collation_connection: utf8_general_ci Database Collation: utf8_general_ci1 row in set (0.00 sec)ERROR:No query specified
限制和注意事項
觸發器會有以下兩種限制:
1.觸發程序不能調用將數據返回客戶端的存儲程序,也不能使用采用CALL語句的動態SQL語句,但是允許存儲程序通過參數將數據返回觸發程序,也就是存儲過程或者函數通過OUT或者INOUT類型的參數將數據返回觸發器是可以的,但是不能調用直接返回數據的過程.
2.不能再觸發器中使用以顯示或隱式方式開始或結束事務的語句,如START TRANS-ACTION,COMMIT或ROLLBACK.
注意事項:MySQL的觸發器是依照BEFORE觸發器、行操作、AFTER觸發器的順序執行的,其中任何一步發生錯誤都不會繼續執行剩下的操作,如果對事務表進行的操作,如果出現錯誤,那么將會被回滾,如果是對非事務表進行操作,那么就無法回滾了,數據可能會出錯.
總結
觸發器是基于行觸發的,所以刪除、新增或者修改操作可能都會激活觸發器,所以不要編寫過于復雜的觸發器,也不要增加過得的觸發器,這樣會對數據的插入、修改或者刪除帶來比擬嚴重的影響,同時也會帶來可移植性差的后果,所以在設計觸發器的時候一定要有所考慮.
歡迎參與《MySQL之觸發器》討論,分享您的想法,維易PHP學院為您提供專業教程。
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/7874.html