mysql触发器trigger 实例详解
MySQL好像從5.0.2版本就開始支持觸發器的功能了
創建觸發器
CREATE TRIGGER trigger_name trigger_time trigger_event ON tb_name FOR EACH ROW trigger_stmt trigger_name:觸發器的名稱 tirgger_time:觸發時機,為BEFORE或者AFTER trigger_event:觸發事件,為INSERT、DELETE或者UPDATE tb_name:表示建立觸發器的表明,就是在哪張表上建立觸發器 trigger_stmt:觸發器的程序體,可以是一條SQL語句或者是用BEGIN和END包含的多條語句 所以可以說MySQL創建以下六種觸發器: BEFORE INSERT,BEFORE DELETE,BEFORE UPDATE AFTER INSERT,AFTER DELETE,AFTER UPDATEBEGIN與END之間的執行語句列表參數表示需要執行的多個語句,不同語句用分號隔開
tips:一般情況下,mysql默認是以 ; 作為結束執行語句,與觸發器中需要的分行起沖突
?? 為解決此問題可用DELIMITER,如:DELIMITER ||,可以將結束符號變成||
? 當觸發器創建完成后,可以用DELIMITER ;來將結束符號變成;
mysql> DELIMITER || mysql> CREATE TRIGGER demo BEFORE DELETE-> ON users FOR EACH ROW-> BEGIN-> INSERT INTO logs VALUES(NOW());-> INSERT INTO logs VALUES(NOW());-> END-> || Query OK, 0 rows affected (0.06 sec)mysql> DELIMITER ;tigger_event:
?
load data語句是將文件的內容插入到表中,相當于是insert語句,而replace語句在一般的情況下和insert差不多,但是如果表中存在primary 或者unique索引的時候,如果插入的數據和原來的primary key或者unique相同的時候,會刪除原來的數據,然后增加一條新的數據,所以有的時候執行一條replace語句相當于執行了一條delete和insert語句。
在BEGIN...END語句中也可以定義變量,但是只能在BEGIN...END內部使用:
DECLARE var_name var_type [DEFAULT value] #定義變量,可指定默認值 SET var_name = value #給變量賦值NEW和OLD的使用:
?NEW.columnname:新增行的某列數據
OLD.columnname:刪除行的某列數據
用戶users表
CREATE TABLE `users` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL,`add_time` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `name` (`name`(250)) USING BTREE ) ENGINE=MyISAM AUTO_INCREMENT=1000001 DEFAULT CHARSET=latin1;日志logs表:
CREATE TABLE `logs` (`Id` int(11) NOT NULL AUTO_INCREMENT,`log` varchar(255) DEFAULT NULL COMMENT '日志說明',PRIMARY KEY (`Id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='日志表';需求是:當在users中插入一條數據,就會在logs中生成一條日志信息。
DELIMITER $ CREATE TRIGGER user_log AFTER INSERT ON users FOR EACH ROW BEGIN DECLARE s1 VARCHAR(40)character set utf8; DECLARE s2 VARCHAR(20) character set utf8;#后面發現中文字符編碼出現亂碼,這里設置字符集 SET s2 = " is created"; SET s1 = CONCAT(NEW.name,s2); #函數CONCAT可以將字符串連接 INSERT INTO logs(log) values(s1); END $ DELIMITER ;查看觸發器
SHOW TRIGGERS語句查看觸發器信息
drop trigger user_log;#刪除觸發器
tips:SHOW TRIGGERS語句無法查詢指定的觸發器
tips:所有觸發器信息都存儲在information_schema數據庫下的triggers表中
?? 可以使用SELECT語句查詢,如果觸發器信息過多,最好通過TRIGGER_NAME字段指定查詢
回到上面,我們創建好了觸發器,繼續在users中插入數據并查看數據:
insert into users(name,add_time) values('周伯通',now());好吧,我們再來查看一下logs表吧!
限制和注意事項
觸發器會有以下兩種限制:
1.觸發程序不能調用將數據返回客戶端的存儲程序,也不能使用采用CALL語句的動態SQL語句,但是允許存儲程序通過參數將數據返回觸發程序,也就是存儲過程或者函數通過OUT或者INOUT類型的參數將數據返回觸發器是可以的,但是不能調用直接返回數據的過程。
2.不能再觸發器中使用以顯示或隱式方式開始或結束事務的語句,如START TRANS-ACTION,COMMIT或ROLLBACK。
注意事項:MySQL的觸發器是按照BEFORE觸發器、行操作、AFTER觸發器的順序執行的,其中任何一步發生錯誤都不會繼續執行剩下的操作,如果對事務表進行的操作,如果出現錯誤,那么將會被回滾,如果是對非事務表進行操作,那么就無法回滾了,數據可能會出錯。
總結
不要編寫過于復雜的觸發器,也不要增加過多的觸發器,這樣會對數據的插入、修改或者刪除帶來比較嚴重的影響,同時也會帶來可移植性差的后果,所以在設計觸發器的時候一定要有所考慮。
觸發器是一種特殊的存儲過程,它比數據庫本身標準的功能有更精細和更復雜的數據控制能力。
數據庫觸發器有以下的作用:
1.安全性。可以基于數據庫的值使用戶具有操作數據庫的某種權利。
??# 可以基于時間限制用戶的操作,例如不允許下班后和節假日修改數據庫數據。
??# 可以基于數據庫中的數據限制用戶的操作,例如不允許股票的價格的升幅一次超過10%。
2.審計??梢愿櫽脩魧祿斓牟僮?。???
??# 審計用戶操作數據庫的語句。
??# 把用戶對數據庫的更新寫入審計表。
3.實現復雜的數據完整性規則
??# 實現非標準的數據完整性檢查和約束。觸發器可產生比規則更為復雜的限制。與規則不同,觸發器可以引用列或數據庫對象。例如,觸發器可回退任何企圖吃進超過自己保證金的期貨。
??# 提供可變的缺省值。
4.實現復雜的非標準的數據庫相關完整性規則。觸發器可以對數據庫中相關的表進行連環更新。例如,在auths表author_code列上的刪除觸發器可導致相應刪除在其它表中的與之匹配的行。
??# 在修改或刪除時級聯修改或刪除其它表中的與之匹配的行。
??# 在修改或刪除時把其它表中的與之匹配的行設成NULL值。
??# 在修改或刪除時把其它表中的與之匹配的行級聯設成缺省值。
??# 觸發器能夠拒絕或回退那些破壞相關完整性的變化,取消試圖進行數據更新的事務。當插入一個與其主健不匹配的外部鍵時,這種觸發器會起作用。例如,可以在books.author_code?列上生成一個插入觸發器,如果新值與auths.author_code列中的某值不匹配時,插入被回退。
5.同步實時地復制表中的數據。
6.自動計算數據值,如果數據的值達到了一定的要求,則進行特定的處理。例如,如果公司的帳號上的資金低于5萬元則立即給財務人員發送警告數據。
總結
以上是生活随笔為你收集整理的mysql触发器trigger 实例详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CPC客户端打开报错:未在本地计算机上注
- 下一篇: 一氧化碳(CO)荧光探针cas85575