1. 程式人生 > 其它 >SQL學習筆記-------第八天(觸發器實現多表同步更新學生資訊)

SQL學習筆記-------第八天(觸發器實現多表同步更新學生資訊)

技術標籤:sql學習sql資料庫

觸發器實現多表同步更新學生資訊--目錄


1.什麼是觸發器?

觸發器是由一段程式碼塊組成,當表中的資料發生變化(如INSERT、UPDATE 或 DELETE )時,會自動喚醒呼叫觸發器中的程式碼,從而起到了保證業務規則和資料的完整性的作用。

比如在網上商城系統中,當商家的一個商品被使用者購買時,在訂單表生成資料的同時,需要從商家庫存表中減去該商品。

還有當一個商家賬戶登出時,刪除使用者表中該商家記錄的同時,還需要將商家對應的商品資料,銷售訂單記錄和庫存記錄等資訊刪除,這些都可以使用觸發器來完成。

觸發器也可以起到欄位約束的作用,用來檢查欄位的新增值是否符合規則,如果異常及時返回錯誤,阻塞插入。

2.建立觸發器

不同資料庫建立觸發器的語法存在細微的差距,在MariaDB(MySQL分支)中建立觸發器語法如下:

create trigger trigger_name trigger_time trigger_event on table_name for each now trigger_stmt

其中:

  • trigger_name:觸發器名稱,開發者自定義;
  • trigger_time:什麼時候觸發,取值為BEFORE或AFTER,表示是在trigger_event事件之前還是之後執行觸發器。
  • trigger_event:觸發事件,取值為insert、update、delete;
  • table_name:觸發器相關聯的表名,即在哪張表上進行操作室執行觸發器。
  • trigger_stmt:觸發器程式碼塊,一條或多條SQL語句;
  • fo reach now:每影響一行記錄,就觸發執行一次觸發器的SQL;

從 trigger_time 和 trigger_event 的組合來看可以建立 6 種觸發器,即:BEFORE INSERT、BEFORE
UPDATE、BEFORE DELETE、AFTER INSERT、AFTER UPDATE、AFTER DELETE;

另外在 MariaDB 中限制在同一張表不能建立兩種相同型別的觸發器,因此在一張表最多建立6個觸發器。

以下 SQL 指令碼是在 MariaDB 中的學生選課成績表 elective 上建立 after insert 的觸發器,它的主要作用是在當向學生選課資訊 student 表新增一條記錄後,更新學生資訊表中對應學生的總學分成績。

delimiter //
drop trigger if exists tri_elective_insert //
create trigger tri_elective_insert after insert
on elective for each row
begin
declare number int;
select (case when grade >= 60 then 5 else 4 end ) into number from elective where id= new.id;
update student set sum_grade = number +  ifnull(sum_grade,0) where sid = new.sid;
end //
delimiter ;

可以看到上面指令碼中定義了 new 和 old 這兩個關鍵字代表 elective 表觸發了觸發器的那行資料,new表示修改後 (update語句)或插入 (insert語句)的新記錄,相反 old 表示修改前(update語句)或被刪除(delete語句)的原資料。

SQL指令碼中的關鍵字 DELIMITER 起到申明 SQL 語句結束符的作用,當然,MySQL 結束符是可以自由設定的,可以用 “/” 或者“$$”等字元 ,如果不設定結束符,MySQL 的預設 SQL 語句結束符為";"。

由於上面 SQL 指令碼是一個整體,需要通過 DELIMITER 申明結束符"//",讓資料庫明白,當再次遇到這個符號時指令碼才算完整,可以執行前面的指令碼了,指令碼最後需要將結束符重新改為分號:DELIMITER ;

我們通過以下SQL指令碼測試下剛剛建立的觸發器 tri_elective_insert:

insert into elective(sid,cid,createtime,grade) values('1006','31',now(),93);
 select  * from student where sid='1006';

當執行上面的指令碼向學生成績資訊表 elective 新增一條記錄時,會觸發觸發器中指令碼的執行,通過查詢 SQL 可以看到編號為 1006 的總學分成績從 0 已經變成了 5。
在這裡插入圖片描述

3.檢視和刪除觸發器

在 MySQL 中檢視觸發器,使用下面的SQL語句:

show triggers

結果集:
在這裡插入圖片描述

查詢語句會輸出當前庫所有的觸發器,如果希望查詢一張表的觸發器,可以通過查詢系統表information_schema.triggers 來實現,比如查詢 elective表中的所有的觸發器:

select * from information_schema.triggers  where event_object_table='elective'

結果集:
在這裡插入圖片描述
MySQL 資料庫提供了刪除觸發器的語法:

DROP TRIGGER [if exists] trigger_name --刪除觸發器 

值得注意的是,如果觸發器不需要了一定及時刪除,以免造成意外操作導致資料的混亂。

4.小結

本節我們一起學習了資料庫表的觸發器,但這裡給大家的建議是在專案開發過程中,儘量不要使用觸發器,這是為什麼呢? 主要有以下兩點考慮:

  1. 假如我們想向表 elective 中插入上萬條記錄,那麼觸發器就會被觸發上萬次,觸發器的每次執行都會消耗資源,
  2. 觸發的次數越多,相應消耗的資源越多;
  3. 觸發器對開發者來說是自動執行的,當出現數據不一致或資料混亂時,不容易定位問題,觸發器的程式碼也是最容易被忽略的;
  4. 如果已經使用了觸發器,那麼可以考慮將觸發器中的程式碼遷移到儲存過程中或者寫入應用程式中處理,這樣可以規避觸發器帶來的負面影響。

---------------------------------------------------------總結自慕課網(10年DBA玩轉SQL)一文----------------------------------------------