業務需要,要同步兩個數據庫的用戶信息,因此用到了觸發器。
觸發器是純數據庫操作,與項目代碼無關。
觸發器是數據庫表的屬性,是一個特殊的存儲過程,觸發器是個特殊的存儲過程,但是觸發器不需要CALL語句調用,也不需要手動啟動。它由事件觸發,事件包括INSERT,UPDATE和DELETE語句,當表中出現這些特定事件時,將激活該對象 。MySQL5.0.2開始支持。
觸發器和觸發事件是一個原子操作,不用擔心數據完整性。
無法在一個時間上創建兩個觸發器。
一、創建觸發器
語法:
①:單SQL語句語法
CREATE TRIGGER synchronization_user_insert AFTER INSERT ON user_table
FOR EACH ROW
INSERT INTO b.user2(`id`,`name`)
VALUES(NEW.id,NEW.name);
#什么時候觸發after或者before;操作事件(觸發器類型)包括 insert,update,delete; ON 后面綁定表名
#for each row每一行受影響,影響范圍
# b表示不同的數據庫庫名,同一個數據庫可省略。可見觸發器是一個全局函數
#NEW表示操作后新的值,OLD表示操作前的值
②:創建有多個執行語句的觸發器: (MySQL默認以分號結尾)
DELIMITER //
CREATE TRIGGER synchronization_user_insert AFTER INSERT ON user_table
FOR EACH ROW
BEGIN
INSERT INTO b.user2(`id`,`name`)
VALUES(NEW.id,NEW.name);
END //
DELIMITER ;
③:if語句觸發器
DELIMITER //
CREATE TRIGGER 觸發器名稱 AFTER INSERT ON 表名
FOR EACH ROW
if 判斷條件 THEN
執行SQL語句1;
ELSE 執行SQL語句2;
END if;
//
DELIMITER ;
④:case語句
DELIMITER //
CREATE TRIGGER 觸發器名稱 AFTER INSERT ON 表名
FOR EACH ROW
CASE
WHEN 執行SQL語句1;
WHEN 執行SQL語句2;
END CASE;
//
DELIMITER ;
二、查看觸發器
SHOW TRIGGERS;
三、刪除觸發器
DROP TRIGGER [數據庫名稱.]觸發器名稱;
四、實際使用記錄
在單SQL語句時,是不用加begin和end的。第一次加了成功創建了觸發器,但是在業務執行時出錯。顯示找不到B數據庫的B表
剛開始以為是JDBC數據源連接的問題因為是報了這個錯,但是觸發器是純數據庫的操作,跟這些無關。又考慮到賬號權限的問題,但是root。最后在log日志發現下面的問題,所以看日志還是要看下面具體問題的原因分析。
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`qibao_business`.`userdetail`, CONSTRAINT `fk_UserDetail_suyidept` FOREIGN KEY (`reptId`) REFERENCES `suyidept` (`id`))
很明顯這是一個主外鍵關聯的錯誤!
引用大佬的話:
!!盡量少使用觸發器。
假設觸發器觸發每次執行1s,insert table 500條數據,那么就需要觸發500次觸發器,光是觸發器執行的時間就花費了500s,而insert 500條數據一共是1s,那么這個insert的效率就非常低了。因此我們特別需要注意的一點是觸發器的begin end;之間的語句的執行效率一定要高,資源消耗要小。
觸發器盡量少的使用,因為不管如何,它還是很消耗資源,如果使用的話要謹慎的使用,確定它是非常高效的:觸發器是針對每一行的;對增刪改非常頻繁的表上切記不要使用觸發器,因為它會非常消耗資源。
為什么大家都不推薦使用MySQL觸發器而用存儲過程?- segmentfault
回答1:
1.存儲過程和觸發器二者是有很大的聯系的,我的一般理解就是觸發器是一個隱藏的存儲過程,因為它不需要參數,不需要顯示調用,往往在你不知情的情況下已經做了很多操作。從這個角度來說,由於是隱藏的,無形中增加了系統的復雜性,非DBA人員理解起來數據庫就會有困難,因為它不執行根本感覺不到它的存在。
2.再有,涉及到復雜的邏輯的時候,觸發器的嵌套是避免不了的,如果再涉及幾個存儲過程,再加上事務等等,很容易出現死鎖現象,再調試的時候也會經常性的從一個觸發器轉到另外一個,級聯關系的不斷追溯,很容易使人頭大。其實,從性能上,觸發器並沒有提升多少性能,只是從代碼上來說,可能在coding的時候很容易實現業務,所以我的觀點是:摒棄觸發器!觸發器的功能基本都可以用存儲過程來實現。
3.在編碼中存儲過程顯示調用很容易閱讀代碼,觸發器隱式調用容易被忽略。
4.存儲過程的致命傷在於移植性,存儲過程不能跨庫移植,比如事先是在mysql數據庫的存儲過程,考慮性能要移植到oracle上面那么所有的存儲過程都需要被重寫一遍。