MySql触发器以及实例
一、什么觸發器
???官方定義:觸發器(trigger)是個特殊的存儲過程,它的執行不是由程序調用,也不是手工啟動,而是由事件來觸發,比如當對一個表進行操作( insert,delete,update)時就會激活它執行。觸發器經常用于加強數據的完整性約束和業務規則等。觸發器可以從 DBA_TRIGGERS ,USER_TRIGGERS 數據字典中查到。
??? 觸發器有一個非常好的特性就是:觸發器可以禁止或回滾違反引用完整性的更改,從而取消所嘗試的數據修改。
什么意思,舉個例子解釋一下,街機游戲大家都玩過吧,闖過一關,闖下一關,有一關沒闖過就要從第一關開始。觸發器根這個類似。
官方解釋如下
??? 觸發程序視為單一交易中的一部份,因此可以由原觸發程序還原交易,如果在交易過程中偵測到嚴重的錯誤(如使用者中斷連線),則會自動還原整個交易。
??? 他的作用很明顯了,可以保重數據的完整性,下面有一個實例來說明他的好處,以及如果使編寫代碼不那么復雜。
二、觸發器語法
create triggertrigger_nametrigger_time trigger_event
on tbl_name for each row trigger_stmt
???觸發程序與命名為tbl_name的表相關。
???trigger_time是觸發程序的動作時間。它可以是BEFORE或AFTER,以指明觸發程序是在激活它的語句之前或之后觸發。
???trigger_event指明了激活觸發程序的語句的類型。trigger_event可以是下述值之一:
INSERT:將新行插入表時激活觸發程序,例如,通過INSERT、LOAD DATA和REPLACE語句。
UPDATE:更改某一行時激活觸發程序,例如,通過UPDATE語句。
DELETE:從表中刪除某一行時激活觸發程序,例如,通過DELETE和REPLACE語句。
???請注意,trigger_event與以表操作方式激活觸發程序的SQL語句并不很類似,這點很重要。例如,關于INSERT的BEFORE觸發程序不僅能被INSERT語句激活,也能被LOAD DATA語句激活。
可能會造成混淆的例子之一是INSERT INTO .. ON DUPLICATE UPDATE ...語法:BEFORE INSERT觸發程序對于每一行將激活,后跟AFTER INSERT觸發程序,或BEFORE UPDATE和AFTER UPDATE觸發程序,具體情況取決于行上是否有重復鍵。
??? 對于具有相同觸發程序動作時間和事件的給定表,不能有兩個觸發程序。例如,對于某一表,不能有兩個BEFORE UPDATE觸發程序。但可以有1個BEFORE UPDATE觸發程序和1個BEFOREINSERT觸發程序,或1個BEFORE UPDATE觸發程序和1個AFTER UPDATE觸發程序。
trigger_stmt是當觸發程序激活時執行的語句。如果你打算執行多個語句,可使用BEGIN ... END復合語句結構。這樣,就能使用存儲子程序中允許的相同語句
MySQL數據庫創建觸發器的格式如下:
| create trigger <觸發器名稱> |
?
createtrigger<觸發器名稱>:創建一個新觸發器,并指定觸發器的名稱。
{before|after}:用于指定在insert、update或delete語句執行前觸發還是在語句執行后觸發。
on<表名>:用于指定響應該觸發器的表名。
for each row:觸發器的執行間隔,for each row通知觸發器每隔一行執行一次動作,而不是對整個表執行一次。
<觸發器SQL語句>:觸發器要執行的SQL語句,如果該觸發器要執行多條SQL語句,要將多條語句放在begin…end塊中。
三、創建觸發器
1.用戶表users
?
create table users (?
id int primary key not null auto_incrementcomment '用戶id',?
name varchar(50) not null default ''comment '名稱',?
sex int not null default '0' comment '0為男,1為女'
)
insert into users (id, name, sex)values?
(1, '張三', 0),?
(2,李四, 0);
?
2.評論表comment
create table comment (?
c_id int primary key not nullauto_increment comment '評論id',?
u_id int not null comment '用戶id',?
name varchar(50) not nulldefault '' comment '用戶名稱',?
content varchar(1000) notnull default '' comment '評論內容'?
)?
?
?
insert into comment (c_id,u_id, name, content) values?
(1, 1, '張三', '觸發器測試'),?
(2, 1, '張三', '解決字段冗余'),?
(3, 2, '李四', '使代碼更簡單');
?
???我要做的事情是,當我更新users表的name時,觸發器同時更新comment表,就不要寫代碼去更新了,當用戶被刪除時,comment表中,有關該用戶的數據將被刪除
?
3.觸發器更新數據
create trigger updatenameafter update on users for each row??-- 建立觸發器,?
begin?-- old,new都是代表當前操作的記錄行,你把它當成表名,也行
if new.name!=old.namethen?-- 當表中用戶名稱發生變化時,執行?
update comment setcomment.name=new.name where comment.u_id=old.id;?
end if;?
end
?
4.觸發器刪除數據
create trigger deletecommentbefore delete on users for each row?
begin?
delete from comment wherecomment.u_id=old.id;?
end
?
5.測試觸發器是否可用
a.測試update觸發器
update user set name='老王' where id = 1;
b.delete觸發器
delete from user? whereid = 1;
四、觸發器的優點
1、觸發器的"自動性"
??? 對程序員來說,觸發器是看不到的,但是他的確做事情了,如果不用觸發器的話,你更新了user表的name字段時,你還要寫代碼去更新其他表里面的冗余字段,我舉例子,只是一張表,如果是幾張表都有冗余字段呢,你的代碼是不是要寫很多呢,看上去是不是很不爽呢。
2、觸發器的數據完整性
??? 觸發器有回滾性,舉個例子,就是你要更新五張表的數據,不會出現更新了二個張表,而另外三張表沒有更新。
??? 但是如果是用代碼去寫的話,就有可能出現這種情況的,比如你更新了二張表的數據,這個時候,數據庫掛掉了。你就郁悶了,有的更新了,有的沒更新。這樣頁面顯示不一致了,變有bug了。
注意:
???使用old和new關鍵字,能夠訪問受觸發程序影響的行中的列(old和new不區分大小寫)。在INSERT觸發程序中,僅能使用NEW.col_name,沒有舊行。在DELETE觸發程序中,僅能使用OLD.col_name,沒有新行。在UPDATE觸發程序中,可以使用OLD.col_name來引用更新前的某一行的列,也能使用NEW.col_name來引用更新后的行中的列。
???用old命名的列是只讀的。你可以引用它,但不能更改它。對于用new命名的列,如果具有SELECT權限,可引用它。在BEFORE觸發程序中,如果你具有UPDATE權限,可使用“SET NEW.col_name = value”更改它的值。這意味著,你可以使用觸發程序來更改將要插入到新行中的值,或用于更新行的值。
???在BEFORE觸發程序中,AUTO_INCREMENT列的NEW值為0,不是實際插入新記錄時將自動生成的序列號。
總結
以上是生活随笔為你收集整理的MySql触发器以及实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信开发学习日记(一):快速阅读5本书,
- 下一篇: hdu 4280 最大流sap