1. 程式人生 > >MYSQL常見概念二 : 觸發器

MYSQL常見概念二 : 觸發器

定義:資料庫某張表的增加、刪除、更新的操作觸發預先定義的sql執行

 特性:  引起觸發器執行的操作與觸發器內定義的sql,要麼一起執行,要麼一起不執行

 應用場景:  1.   資料備份,往一張表插入資料,需要往另外一張表同步時

                    2.   同步更新,更新一張表資料時,同時更新多張表相應資料,比如更改了使用者名稱,在所有有改使用者名稱的表都做

                                          相應更新

                    3.  想幹以上兩件事,又不想動線上程式碼

 缺點:  容易與程式碼邏輯重疊,開發人員維護困難;單純使用觸發器,可能會引起資料不一致(出錯無法回滾),可與事務結合使用

 建立觸發器語法: 

CREATE TRIGGER trigger_name   -- 要建立的觸發名稱
trigger_time                  -- 觸發器執行時間,值為 BEFORE 或 AFTER
trigger_event                 -- 觸發事件,值為 INSERT、UPDATE 或 DELETE 
ON tbl_name                   -- 在哪個表上建立觸發器
FOR EACH ROW                  -- 對更改/插入/刪除的每一行執行
trigger_stmt                  -- 觸發器sql,一句SQL語句或者用 BEGIN 和 END包含的多條語句

例項:

首先建立兩張表:

DROP TABLE IF EXISTS users ;
CREATE TABLE `users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `pass` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


DROP TABLE IF EXISTS institution_users;
CREATE TABLE `institution_users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `institution_id` int(11) unsigned,
  `user_id` int(11) unsigned,
  `user_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `created_at` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

 1.1 建立 insert觸發器,往users表插入資料時同時觸發往institution_users插入資料

DROP TRIGGER IF EXISTS  insert_users_to_institution_users;   -- 如果有觸發器先刪除
CREATE TRIGGER insert_users_to_institution_users   -- 要建立的觸發名稱
AFTER                                              -- 觸發器執行時間,值為 BEFORE 或 AFTER
INSERT                                             -- 觸發事件,值為 INSERT、UPDATE 或 DELETE 
ON users                                            -- 在哪個表上建立觸發器
FOR EACH ROW                                       -- 對更改/插入/刪除的每一行執行
BEGIN                                              -- 觸發器sql,一句SQL語句或者用 BEGIN 和 END包含的多條語句
    INSERT INTO institution_users(institution_id,user_id,user_name,created_at) VALUES(170,new.id,new.name,NOW());
END

1.2 執行insert ,往users表插入一條資料

INSERT INTO users(name,pass,created_at) VALUES('test_trigger','123456',NOW());

    執行成功後,檢視 institution_users表,可以發現已經多了條記錄

2.1 建立 update觸發器,往users表更新資料時同時觸發往institution_users更新資料

DROP TRIGGER IF EXISTS  update_users_to_institution_users;   -- 如果有觸發器先刪除
CREATE TRIGGER update_users_to_institution_users   -- 要建立的觸發名稱
AFTER                                              -- 觸發器執行時間,值為 BEFORE 或 AFTER
UPDATE                                             -- 觸發事件,值為 INSERT、UPDATE 或 DELETE 
ON users                                            -- 在哪個表上建立觸發器
FOR EACH ROW                                       -- 對更改/插入/刪除的每一行執行
BEGIN                                              -- 觸發器sql,一句SQL語句或者用 BEGIN 和 END包含的多條語句
    update institution_users set user_name = new.name WHERE user_id = new.id;
END

2.2 執行成功後執行以下sql語句,會發現institution_users也有對應更新

UPDATE users SET name = 'dev_trigger'  WHERE name = 'test_trigger' ;

3.1 建立 delete觸發器  ,刪除users表資料時同時觸發刪除institution_users資料

DROP TRIGGER IF EXISTS  delete_users_to_institution_users;   -- 如果有觸發器先刪除
CREATE TRIGGER delete_users_to_institution_users   -- 要建立的觸發名稱
AFTER                                              -- 觸發器執行時間,值為 BEFORE 或 AFTER
DELETE                                            -- 觸發事件,值為 INSERT、UPDATE 或 DELETE 
ON users                                            -- 在哪個表上建立觸發器
FOR EACH ROW                                       -- 對更改/插入/刪除的每一行執行
BEGIN                                              -- 觸發器sql,一句SQL語句或者用 BEGIN 和 END包含的多條語句
    DELETE from institution_users  WHERE user_id = old.id;
END

3.2 執行成功後執行以下sql語句,會發現institution_users也有對應刪除

DELETE FROM users WHERE name = 'dev_trigger'