一、觸發器概述
觸發器(Trigger)是一種特殊的存儲過程,它與表緊密相連,可以是定義表的一部分。當預定義的事件(如用戶修改指定表或者視圖中的數據)發生時,觸發器將會自動執行。
觸發器基於一個表創建,但是可以針對多個表進行操作。所以觸發器可以用來對表實施復雜的完整性約束,當觸發器所保存的數據改變時,觸發器被自動激活,從而防止對數據進行不正確的修改。觸發器的有點如下所述。
(1)觸發器自動執行,在表的數據做了任何修改(比如手工輸入或者使用程序采集的操作)之后立即激活。
(2)觸發器可以通過數據庫中的相關表進行層疊更改。這比直接把代碼寫在前台的做法更安全合理。
(3)觸發器可以強制限制,這些限制比用 CHECK 約束所定義的更復雜。與 CHECK 約束不同的是,觸發器可以引用其他表中的列。
二、創建觸發器
因為觸發器是一種特殊的存儲過程,所以觸發器的創建和存儲過程的創建方式有很多相似之處,其基本語法如下。
create trigger trigger_name trigger_time trigger_event
on tb_name for each row trigger_statement;
在 create trigger 語法中,各參數含義如下:
(1)trigger_name:要創建的觸發器名稱。
(2)tb_name:建立觸發器的表名,即在哪個表上建立觸發器。tb_name 必須引用永久性表。
(3)trigger_time:指定觸發器觸發的時機。以指明觸發程序是在激活它的語句之前或之后觸發。可以指定 before 或 after。
(4)trigger_event:指明激活觸發程序的語句的類型。trigger_event可以是下述值之一。
① insert:將新行插入表時觸發程序。例如通過 insert、load data和replace語句。
② update:更改某一行時激活觸發程序。例如通過update語句。
③ delete:從表中刪除某一行時激活觸發程序。例如通過delete和raplace語句。
(5)for each row:觸發器的執行間隔,通知觸發器每隔一行執行一次動作,而不是對整個表執行一次。
(6)trigger_statement:指定觸發器所執行的 SQL 語句。可以使用 BEGIN...END 作為開始和結束。
在觸發器的 SQL 語句中,可以關聯表中的任何列,通過使用 OLD 和 NEW 列名來標識,如OLD.col_name\NEW.col_name。OLD.col_name 關聯現有行的一列在被更新或刪除前的值。NEW.col_name 關聯一個新行的插入或更新現有的行的一列的值。
對於 insert 語句,只有NEW 是合法的。對於delete語句,只有OLD是合法的。對於update語句,NEW和OLD可以同時使用。
例子:在gradem數據庫中,當向student表添加一條學生信息時,同時還需要更新class表中的classnumber列,通過創建一個insert觸發器,在用戶每次向student表中添加新的學生信息時便更新響應的班級人數。這個觸發器的名字為trig_classnum,其定義語句如下。
mysql> use gradem; mysql> create trigger trig_classnum -> after insert on student for each now -> update class set number=number+1 -> where classno = left(new.sno,8);
為確保找到學生的班號,利用left()函數取學生學號的前八位。這樣,在輸入學生信息時,如果classno為空,也不會出現在student表中找不到的情況。
例:在gradem數據庫的teacher表中,定義一個觸發器,當一個教師的信息被刪除時,把該教師的編號和姓名添加到delteacher表中。具體代碼如下。
mysql> use gradem; # 創建一個空表 delteacher,表由tno和tname兩列組成。 mysql> create table delteacher select tno, tname from teacher where 1=0; # 創建 teacher 表的觸發器 mysql> create trigger trig_teacher -> after delete on teacher for each row -> insert into delteacher (tno,tname) values(old.tno, old.tname);
例:創建一個觸發器,當student表中的學生學號發生變更時,同時更新sc表中的相應的學生學號信息。
mysql> use gradem; mysql> delimiter && mysql> create trigger trip_snoupdate -> after update on student for each row -> begin -> if new.sno != old.sno then -> update sc set sno = new.sno where sno=old.sno; -> end if; -> end && Query OK, 0 afected mysql> delimiter ;
三、管理觸發器
3.1 查看觸發器
查看觸發器是指查看數據庫中已經存在的觸發器的定義、狀態和語法信息等。
(1)SHOW TRIGERS
show triggers;
(2)
select * from information_schema.triggers;
3.2 刪除觸發器
使用 DROP TRIGGER 語句可以刪除觸發器。
drop trigger [dbname.]trig_name;
結束!