SQL Server觸發(fā)器的使用解讀
SQL Server 觸發(fā)器
觸發(fā)器(trigger)是SQL server 提供給程序員和數(shù)據(jù)分析員來保證數(shù)據(jù)完整性的一種方法,它是與表事件相關(guān)的特殊的存儲(chǔ)過程,它的執(zhí)行不是由程序調(diào)用,也不是手工啟動(dòng),而是由事件來觸發(fā),比如當(dāng)對(duì)一個(gè)表進(jìn)行操作( insert,delete, update)時(shí)就會(huì)激活它執(zhí)行。觸發(fā)器經(jīng)常用于加強(qiáng)數(shù)據(jù)的完整性約束和業(yè)務(wù)規(guī)則等。
SQL Server包括三種常規(guī)類型的觸發(fā)器:
- DML觸發(fā)器
- DDL觸發(fā)器
- 登錄觸發(fā)器
1.DML(數(shù)據(jù)操作語言,Data Manipulation Language)觸發(fā)器
DML觸發(fā)器是一些附加在特定表或視圖上的操作代碼,當(dāng)數(shù)據(jù)庫服務(wù)器中發(fā)生數(shù)據(jù)操作語言事件時(shí)執(zhí)行這些操作。
SqlServer中的DML觸發(fā)器有三種:
insert
觸發(fā)器:向表中插入數(shù)據(jù)時(shí)被觸發(fā);update
觸發(fā)器:修改表中數(shù)據(jù)時(shí)被觸發(fā);delete
觸發(fā)器:從表中刪除數(shù)據(jù)時(shí)被觸發(fā)。
當(dāng)遇到下列情形時(shí),應(yīng)考慮使用DML觸發(fā)器:
- 通過數(shù)據(jù)庫中的相關(guān)表實(shí)現(xiàn)級(jí)聯(lián)更改
- 防止惡意或者錯(cuò)誤的insert、update和delete操作,并強(qiáng)制執(zhí)行check約束定義的限制更為復(fù)雜的其他限制。
- 評(píng)估數(shù)據(jù)修改前后表的狀態(tài),并根據(jù)該差異才去措施。
2.DDL(數(shù)據(jù)定義語言,Data Definition Language)觸發(fā)器
DDL觸發(fā)器是當(dāng)服務(wù)器或者數(shù)據(jù)庫中發(fā)生數(shù)據(jù)定義語言(主要是以create,drop,alter開頭的語句)事件時(shí)被激活使用
使用DDL觸發(fā)器可以防止對(duì)數(shù)據(jù)架構(gòu)進(jìn)行的某些更改或記錄數(shù)據(jù)中的更改或事件操作
3.登錄觸發(fā)器
登錄觸發(fā)器將為響應(yīng) LOGIN 事件而激發(fā)存儲(chǔ)過程。與 SQL Server 實(shí)例建立用戶會(huì)話時(shí)將引發(fā)此事件。
登錄觸發(fā)器將在登錄的身份驗(yàn)證階段完成之后且用戶會(huì)話實(shí)際建立之前激發(fā)。因此,來自觸發(fā)器內(nèi)部且通常將到達(dá)用戶的所有消息(例如錯(cuò)誤消息和來自 PRINT 語句的消息)會(huì)傳送到 SQL Server 錯(cuò)誤日志。
如果身份驗(yàn)證失敗,將不激發(fā)登錄觸發(fā)器。
DML觸發(fā)器
DML
觸發(fā)器執(zhí)行時(shí),系統(tǒng)內(nèi)存會(huì)自動(dòng)生成deleted表或inserted表,執(zhí)行結(jié)束會(huì)自動(dòng)消失。Insert
觸發(fā)器,使用到inserted表;Update
觸發(fā)器,使用到deleted表和inserted表;Delete
觸發(fā)器,使用到deleted表。
下面引用一張圖,簡單明了展示了DML觸發(fā)器:
DML觸發(fā)器Demo
表結(jié)構(gòu)如下:
Insert 觸發(fā)器:
在向目標(biāo)表中插入數(shù)據(jù)后,會(huì)觸發(fā)該表的Insert 觸發(fā)器,系統(tǒng)自動(dòng)在內(nèi)存中創(chuàng)建inserted表; 下面的demo中對(duì)Age加了判斷,如果不滿足判斷數(shù)據(jù)會(huì)進(jìn)行回滾,插入的數(shù)據(jù)操作會(huì)失敗。
--Insert 觸發(fā)器 Create TRIGGER [dbo].[Trigger_Insert] ON [dbo].[Person] AFTER INSERT AS BEGIN SET NOCOUNT ON; Declare @age int; Select @age=Age From inserted --如果年齡小于150正常插入,否則數(shù)據(jù)回滾 IF(@age<150) Begin Insert into PersonLog(PersonID, Name, Age, AddDate) Select ID, Name, Age, AddDate From inserted End ELSE Begin print('年齡應(yīng)小于150') rollback transaction --數(shù)據(jù)回滾 END END
Update 觸發(fā)器:
在向目標(biāo)表中更新數(shù)據(jù)后,會(huì)觸發(fā)該表的Update 觸發(fā)器,系統(tǒng)自動(dòng)在內(nèi)存中創(chuàng)建deleted表和inserted表,deleted表存放的是更新前的數(shù)據(jù),inserted表存放的是更新的數(shù)據(jù)。
--Update 觸發(fā)器 Create TRIGGER [dbo].[Trigger_Update] ON [dbo].[Person] AFTER UPDATE AS BEGIN SET NOCOUNT ON; --這里是先刪除后插入,存在一張臨時(shí)表deleted Insert Into PersonLog(PersonID, Name, Age, AddDate, UpdateDate) Select ID, Name, Age, AddDate, UpdateDate From inserted END
Delete 觸發(fā)器:
在向目標(biāo)表中刪除數(shù)據(jù)后,會(huì)觸發(fā)該表的Delete 觸發(fā)器,系統(tǒng)自動(dòng)在內(nèi)存中創(chuàng)建deleted表,deleted表存放的是刪除的數(shù)據(jù)。
--Delete 觸發(fā)器 Create TRIGGER [dbo].[Trigger_Delete] ON [dbo].[Person] AFTER DELETE AS BEGIN SET NOCOUNT ON; Insert Into PersonLog(PersonID, Name, Age, AddDate, UpdateDate, DeleteDate) Select ID, Name, Age, AddDate, UpdateDate, GETDATE() From deleted END
觸發(fā)器優(yōu)點(diǎn):
- 1.強(qiáng)化約束:強(qiáng)制復(fù)雜業(yè)務(wù)的規(guī)則和要求,能實(shí)現(xiàn)比check語句更為復(fù)雜的約束。
- 2.跟蹤變化:觸發(fā)器可以偵測數(shù)據(jù)庫內(nèi)的操作,從而禁止數(shù)據(jù)庫中未經(jīng)許可的更新和變化?! ?/li>
- 3.級(jí)聯(lián)運(yùn)行:偵測數(shù)據(jù)庫內(nèi)的操作時(shí),可自動(dòng)地級(jí)聯(lián)影響整個(gè)數(shù)據(jù)庫的各項(xiàng)內(nèi)容。
- 4.嵌套調(diào)用:觸發(fā)器可以調(diào)用一個(gè)或多個(gè)存儲(chǔ)過程。觸發(fā)器最多可以嵌套32層。
觸發(fā)器缺點(diǎn):
- 1. 可移植性差。
- 2.占用服務(wù)器資源,給服務(wù)器造成壓力?! ?/li>
- 3.執(zhí)行速度主要取決于數(shù)據(jù)庫服務(wù)器的性能與觸發(fā)器代碼的復(fù)雜程度?! ?/li>
- 4.嵌套調(diào)用一旦出現(xiàn)問題,排錯(cuò)困難,而且數(shù)據(jù)容易造成不一致,后期維護(hù)不方便。
觸發(fā)器使用建議:
- 1.盡量避免在觸發(fā)器中執(zhí)行耗時(shí)操作,因?yàn)橛|發(fā)器會(huì)與SQL語句認(rèn)為在同一事務(wù)中,事務(wù)不結(jié)束,就無法釋放鎖。
- 2.避免在觸發(fā)器中做復(fù)雜操作,影響觸發(fā)器性能的因素比較多(Eg:產(chǎn)品版本,所使用的架構(gòu)等),要想編寫高效的觸發(fā)器考慮因素比較多,編寫高性能觸發(fā)器還是很難的。
- 3.觸發(fā)器編寫時(shí)注意多行觸發(fā)時(shí)的處理。(一般不建議使用游標(biāo))
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SQL語句實(shí)現(xiàn)刪除ACCESS重復(fù)記錄的兩種方法
有兩個(gè)意義上的重復(fù)記錄,一是完全重復(fù)的記錄,也即所有字段均重復(fù)的記錄,二是部分關(guān)鍵字段重復(fù)的記錄,比如Name字段重復(fù),而其他字段不一定重復(fù)或都重復(fù)可以忽略。2010-04-04sqlserver 用戶權(quán)限管理,LINQ去除它的重復(fù)菜單項(xiàng)
事情是這樣的,我有三張表,用戶_角色關(guān)系表User_Role,角色_菜單關(guān)系表Role_Menu和菜單表2011-08-08SQL Server2008數(shù)據(jù)庫導(dǎo)入導(dǎo)出兼容性處理方案
SQL Server 的高版本數(shù)據(jù)庫恢復(fù)到低版本則可能會(huì)有兼容性問題,下面為大家介紹的是如何解決此類問題2014-05-05Sql Server數(shù)據(jù)遷移的實(shí)現(xiàn)場景及示例
在 SQL Server 中,數(shù)據(jù)遷移是常見的場景之一,本文主要介紹了Sql Server數(shù)據(jù)遷移的實(shí)現(xiàn)場景及示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-04-04SQLServer 使用ADSI執(zhí)行分布式查詢ActiveDorectory對(duì)象
SQLServer 通過使用 ADSI 執(zhí)行分布式查詢ActiveDorectory對(duì)象的實(shí)現(xiàn)方法。2010-05-05mssql server 2012(SQL2012)各版本功能對(duì)比
今天裝了操作系統(tǒng)2012,也順便搞下SQL 2012看了下版本,選擇了自己的版本,也特留下版本對(duì)比供后來人參考2013-04-04sqlserver關(guān)于分頁存儲(chǔ)過程的優(yōu)化【讓數(shù)據(jù)庫按我們的意思執(zhí)行查詢計(jì)劃】
先來對(duì)比兩段分頁SQL,假設(shè)條件:news表有15萬記錄,NewsTypeId=10有9萬記錄,當(dāng)前查詢NewsTypeID=10。那么,你會(huì)認(rèn)為哪個(gè)SQL效率會(huì)高呢?2011-08-08解決Windows 10家庭版安裝SQL Server 2014出現(xiàn).net 3.5失敗問題
在安裝SQL Server 2014的過程中,出現(xiàn).net 3.5缺失,導(dǎo)致失敗問題。怎么解決此問題呢?下面小編給大家分享解決Windows 10家庭版安裝SQL Server 2014出現(xiàn).net 3.5失敗問題,一起看看吧2017-04-04