關於MSDN《瞭解 DML 觸發器》

這是SQLServer基礎知識方面的一片文章,msdn中有關觸發器的介紹文章
<<瞭解 DML 觸發器>>
http://msdn.microsoft.com/zh-cn/library/ms178110.aspx
其中有一段描述

DML 觸發器在以下方面非常有用:

  • DML 觸發器可通過數據庫中的相關表實現級聯更改。不過,通過級聯引用完整性約束可以更有效地進行這些更改。
  • DML 觸發器可以防止惡意或錯誤的 INSERT、UPDATE 以及 DELETE 操作,並強制執行比 CHECK 約束定義的限制更爲複雜的其他限制。
    與 CHECK 約束不同,DML 觸發器可以引用其他表中的列。例如,觸發器可以使用另一個表中的 SELECT 比較插入或更新的數據,以及執行其他操作,如修改數據或顯示用戶定義錯誤信息。
  • DML 觸發器可以評估數據修改前後表的狀態,並根據該差異採取措施。
  • 一個表中的多個同類 DML 觸發器(INSERT、UPDATE 或 DELETE)允許採取多個不同的操作來響應同一個修改語句。

對 於初學者往往會濫用觸發器導致數據庫管理混亂,觸發器是把雙刃劍,慎用.從上面的描述可以看出來,ms還是傾向於在用普通約束或其他sql本身無法解決的 時候才推薦使用觸發器.我個人認爲在類似他列舉的1和3這兩條,在具備條件的情況下應該也少用觸發器,而是在程序中通過事務控制實現.
這裏也不再討論濫用的這個問題,而是對以上ms推薦的四種場景來舉例討論具體應用情況.
1.第一個場景主要是說明某表數據變動,其他依賴表項能同步反映.下面測試語句可以直接運行.

/******************************************

DML 觸發器可通過數據庫中的相關表實現級聯更改

*******************************************/

--測試用例:同步張同構表

--創建測試表

create table a(id int ,name varchar(10))

create table b(id int ,name varchar(10))

go

--建立觸發器

create trigger trg_test

on a

for insert,update,delete

as

begin

if exists (select 1 from deleted)

delete from b where id in(select id from deleted)

if exists (select 1 from inserted)

insert into b select * from inserted

end

go

--測試insert同步

insert into a select 1,'jinjazz'

select * from b

--測試update同步

update a set name='剪刀' where id=1

select * from b

--測試delete同步

delete from a

select * from b

go

drop table a

drop table b


2.第二個場景是一個複雜的約束檢查,這裏的約束採用黑名單模式,分普通觸發器和instead of觸發器兩個測試用例.instead of顧名思義,就是代替(忽略)了insert之類的操作,是前觸發的.

/*************************************************************

DML 觸發器可以防止惡意或錯誤的INSERT、UPDATE 以及DELETE 操作

*************************************************************/

--測試用例:黑名單和回滾

--創建測試表

create table a(id int ,name varchar(10))

create table b(name varchar(10))

insert into b select 'jinjazz'

go

--建立觸發器

create trigger trg_test

on a

for insert

as

begin

if exists(select 1 from inserted where name in(select name from b))

rollback

end

go

--測試插入,此處會有中斷信息請逐條運行

insert into a select 1,'jinjazz'

select * from a

drop table a

drop table b

/*************************************************************

DML 觸發器可以防止惡意或錯誤的INSERT、UPDATE 以及DELETE 操作

*************************************************************/

--測試用例:插入前判斷黑名單

--創建測試表

create table a(id int ,name varchar(10))

create table b(name varchar(10))

insert into b select 'jinjazz'

go

create trigger trg_test1

on a

instead of insert

as

begin

if exists(select 1 from inserted where name in(select name from b))

print '路過,什麼也不做'

else

insert into a select * from inserted

end

go

insert into a select 1,'jinjazz'

select * from a

drop table a

drop table b

3.第三個場景是記錄數據變化過程的,因爲有inserted表和deleted表,他還是有一定的性能優勢的.

/*************************************************************

DML 觸發器可以評估數據修改前後表的狀態,並根據該差異採取措施.

*************************************************************/

--測試用例:差值記錄

--創建測試表

create table a(id int, value int)

create table b(id int,valuechanged int)

go

create trigger trg_test

on a for update

as

begin

declare @v1 int

declare @v2 int

declare @id int

select @v1=value from deleted

select @id=id,@v2=value from inserted

insert into b select @id,@v2-@v1

end

go

insert into a select 1,7

update a set value=10 where id=1

update a set value=20 where id=1

update a set value=8 where id=1

select * from b

go

drop table a

drop table b

4.第四個描述如果我理解的不錯的話,應該是說明一個表可以掛多個同類型觸發器,這樣執行一條sql dml語句就會執行多個觸發器.

/**********************************************************************

一個表中的多個同類DML 觸發器允許採取多個不同的操作來響應同一個修改語句

**********************************************************************/

create table a(id int, name varchar(10))

go

create trigger trg_test

on a

for insert

as

begin

print 'test'

end

go

create trigger trg_test1

on a

for insert

as

begin

print 'test1'

end

go

insert into a select 1,'jinjazz'

drop table a

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章