SQL?SERVER觸發(fā)器詳解
觸發(fā)器是一種特殊的存儲(chǔ)過(guò)程,觸發(fā)器主要是通過(guò)事件進(jìn)行觸發(fā)而被自動(dòng)調(diào)用執(zhí)行,而存儲(chǔ)過(guò)程必須通過(guò)存儲(chǔ)過(guò)程的名稱被調(diào)用。
一、觸發(fā)器的定義
觸發(fā)器是在對(duì)表進(jìn)行插入、更新或刪除操作時(shí)自動(dòng)執(zhí)行的特殊存儲(chǔ)過(guò)程。觸發(fā)器通常用于強(qiáng)制業(yè)務(wù)規(guī)則,觸發(fā)器是一種高級(jí)約束,可以定義比CHECK約束更為復(fù)雜的約束:可以執(zhí)行復(fù)雜的SQL語(yǔ)句(if/while/case),可以引用其他表中的列。觸發(fā)器定義在特定的表上,與表相關(guān),自動(dòng)觸發(fā)執(zhí)行,不能直接調(diào)用,是一個(gè)事務(wù)(可回滾)。
二、觸發(fā)器分類
SQL SERVER中觸發(fā)器可以分為兩類:DML觸發(fā)器和DDL觸發(fā)器,DML觸發(fā)器針對(duì)表,DDL觸發(fā)器會(huì)影響多種數(shù)據(jù)定義語(yǔ)言語(yǔ)句而觸發(fā),這些語(yǔ)句有create、alter、drop語(yǔ)句。
DML觸發(fā)器分為:
1、after觸發(fā)器(之后觸發(fā))
- a、insert觸發(fā)器
- b、update觸發(fā)器
- c、delete觸發(fā)器
2、instead of觸發(fā)器(之前觸發(fā))
after觸發(fā)器要求只有執(zhí)行某一操作(insert、update、delete)之后觸發(fā)器才能被觸發(fā),且只能定義在表上。而instead of觸發(fā)器表示并不執(zhí)行其定義的操作(insert、update、delete)而僅是執(zhí)行觸發(fā)器本身,其優(yōu)先級(jí)高于觸發(fā)語(yǔ)句的執(zhí)行。
觸發(fā)器有兩個(gè)特殊的表:插入表(instered表)和刪除表(deleted表)
這兩張表是邏輯表也是虛表,觸發(fā)器觸發(fā)時(shí)系統(tǒng)自動(dòng)在內(nèi)存中創(chuàng)建這兩張表,不會(huì)存儲(chǔ)在數(shù)據(jù)庫(kù)中。這兩張表都是只讀的,不允許修改。這兩張表的結(jié)果總是與被觸發(fā)器應(yīng)用的表的結(jié)構(gòu)相同。當(dāng)觸發(fā)器完成工作后,這兩張表就會(huì)被刪除。inserted表臨時(shí)保存了插入或更新后的記錄行,可以從inserted表中檢查插入的數(shù)據(jù)是否滿足業(yè)務(wù)需求,如果不滿足,則向用戶報(bào)告錯(cuò)誤消息,并回滾插入操作。deleted表臨時(shí)保存了刪除或更新前的記錄行,可以從deleted表中檢查被刪除的數(shù)據(jù)是否滿足業(yè)務(wù)需求,如果不滿足,則向用戶報(bào)告錯(cuò)誤消息,并回滾刪除操作。update數(shù)據(jù)的時(shí)候是先刪除表記錄,然后插入一條記錄,在inserted和deleted表就都有update后的數(shù)據(jù)記錄了。
inserted表和deleted表存放的信息:
修改操作 | inserted表 | deleted表 |
增加(INSERT)記錄 | 存放新增的記錄 | 無(wú) |
刪除(DELETE)記錄 | 無(wú) | 存放被刪除的記錄 |
修改(UPDATE)記錄 | 存放更新后的記錄 | 存放更新前的記錄 |
三、創(chuàng)建觸發(fā)器
語(yǔ)法:
CREATE TRIGGER trigger_name
ON table_name
[WITH ENCRYPTION]
FOR [DELETE, INSERT, UPDATE]
AS
T-SQL語(yǔ)句
GOWITH ENCRYPTION表示加密觸發(fā)器定義的SQL文本
DELETE, INSERT, UPDATE指定觸發(fā)器的類型
1、創(chuàng)建insert類型的觸發(fā)器
插入觸發(fā)器
--GradeInfo表中插入一條數(shù)據(jù),MyStudentInfo表中插入一條記錄
IF (object_id('tr_insert','tr') is not null)
drop trigger tr_insert
GO
CREATE trigger tr_insert
on GradeInfo
after insert --插入觸發(fā)
as
begin
--定義變量
declare @GradeId int
--在inserted表中查詢已經(jīng)插入記錄信息
select @GradeId=id from INSERTED
--MyStudentInfo表中插入數(shù)據(jù)
insert INTO MyStudentInfo (GradeId) VALUES (@GradeId)
print '插入成功!'
end插入數(shù)據(jù)
insert INTO GradeInfo VALUES (11,'C++')

查詢數(shù)據(jù)
select * from MyStudentInfo where GradeId=11

2、delete觸發(fā)器
刪除MyStudentInfo表中的數(shù)據(jù),插入備份表
--刪除MyStudentInfo表中的數(shù)據(jù),插入備份表
IF (object_id('tr_Delete','tr') is not null)
drop TRIGGER tr_Delete
GO
CREATE trigger tr_Delete
on MyStudentInfo
for delete
as
begin
print '正在備份數(shù)據(jù)......'
IF (object_id('MyStudentInfo_Back','U') is not null)
--存在表,直接插入數(shù)據(jù)
insert INTO MyStudentInfo_Back SELECT * from DELETED
else
select * into MyStudentInfo_Back from DELETED
PRINT '備份完成'
end刪除前查詢MyStudentInfo表數(shù)據(jù)
select * from MyStudentInfo

刪除id=9的數(shù)據(jù)
delete FROM MyStudentInfo where Id=9

查詢備份表數(shù)據(jù)
select * from MyStudentInfo_Back

3、update觸發(fā)器
IF (object_id('tr_Update','tr') is not null)
drop TRIGGER tr_Update
GO
CREATE trigger tr_Update
on MyStudentInfo
for update
as
begin
--聲明變量,存儲(chǔ)更新前和更新后的姓名
declare @OldName varchar(16),@NewName varchar(16)
select @OldName=name from DELETED
print '更新前姓名:'+@OldName
select @NewName=name from INSERTED
print '更新后姓名:'+@NewName
end把張三更新為"張三測(cè)試"
update MyStudentInfo SET Name='張三測(cè)試' where Id=1

update更新列級(jí)觸發(fā)器
--update更新列級(jí)觸發(fā)器
IF (object_id('tr_update_column','tr') is not null)
drop TRIGGER tr_update_column
GO
CREATE trigger tr_update_column
on GradeInfo
for update
as
begin
IF(update(id))
begin
print '系統(tǒng)提示:主鍵ID不能更新'
rollback
end
end
更新id列
update GradeInfo SET Id=15 where Id=4

4、instead of觸發(fā)器
instead of觸發(fā)器表示并不執(zhí)行其定義的操作(insert、update、delete)而僅是執(zhí)行觸發(fā)器本身的內(nèi)容,其優(yōu)先級(jí)高于定義的SQL語(yǔ)句的執(zhí)行
語(yǔ)法:
create trigger tgr_name
on table_name
with encryption
instead of update...
as
begin
T-SQL
end創(chuàng)建instead of觸發(fā)器
--創(chuàng)建instead of觸發(fā)器
/*MyStudentInfo表里面插入數(shù)據(jù)之前,先判斷GradeInfo表中是否有對(duì)應(yīng)的班級(jí)ID,如果沒有,不允許插入,如果存在,則插入 */
IF (object_id('tr_insteadOf','tr') is not null)
drop TRIGGER tr_insteadOf
GO
CREATE trigger tr_insteadOf
on MyStudentInfo
instead of insert
as
begin
IF exists(SELECT * FROM GradeInfo WHERE Id=(SELECT GradeId FROM INSERTED))
print '該班級(jí)存在,可以插入'
else
begin
print '該班級(jí)不存在,不可以插入'
rollback
end
end測(cè)試1,插入不存在的班級(jí)id
insert INTO MyStudentInfo (GradeId) VALUES (15)

測(cè)試2,插入存在的班級(jí)id
insert INTO MyStudentInfo (GradeId) VALUES (5)

DDL觸發(fā)器
? create trigger tr_DDL on database ? for DROP_TABLE,ALTER_TABLE ? as ??? begin ????? print '別想著刪庫(kù)!好好打你的代碼' ?? rollback --回滾 ?end
測(cè)試刪除表
drop TABLE MyStudentInfo

測(cè)試修改表結(jié)構(gòu)
alter table MyStudentInfo alter column Name varchar(32)

禁用DML觸發(fā)器
disable trigger tr_insteadOf on MyStudentInfo
啟用DML觸發(fā)器
enable trigger tr_insteadOf on MyStudentInfo
禁用DDL觸發(fā)器
disable trigger tr_DDL on database
啟用DDL觸發(fā)器
enable trigger tr_DDL on database
到此這篇關(guān)于SQL SERVER觸發(fā)器詳解的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
存儲(chǔ)過(guò)程解密(破解函數(shù),過(guò)程,觸發(fā)器,視圖.僅限于SQLSERVER2000)
解密指定存儲(chǔ)過(guò)程 exec sp_decrypt '存儲(chǔ)過(guò)程名'2009-05-05
MSSQL存儲(chǔ)過(guò)程學(xué)習(xí)筆記一 關(guān)于存儲(chǔ)過(guò)程
在寫筆記之前,首先需要整理好這些概念性的東西,否則的話,就會(huì)在概念上產(chǎn)生陌生或者是混淆的感覺。2011-05-05
SqlServer身份驗(yàn)證登錄配置的實(shí)現(xiàn)步驟
SQL?Server身份驗(yàn)證是一種用于驗(yàn)證用戶身份的方法,本文主要介紹了SqlServer身份驗(yàn)證登錄配置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-04-04
SQL?Server實(shí)現(xiàn)group_concat功能的詳細(xì)實(shí)例
group_concat函數(shù)能將相同的行組合起來(lái),下面這篇文章主要給大家介紹了關(guān)于SQL?Server實(shí)現(xiàn)group_concat功能的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
存儲(chǔ)過(guò)程實(shí)現(xiàn)(可帶查詢條件/萬(wàn)能分頁(yè)/通用)
可帶查詢條件的SQL語(yǔ)句的分頁(yè)存儲(chǔ)過(guò)程,在項(xiàng)目開發(fā)中很實(shí)用,感興趣的朋友可以了解下,希望本文可以鞏固你的存儲(chǔ)過(guò)程的相關(guān)知識(shí)2013-01-01
ACCESS數(shù)據(jù)庫(kù)的壓縮,備份,還原,下載,刪除的實(shí)現(xiàn)
ACCESS數(shù)據(jù)庫(kù)的壓縮,備份,還原,下載,刪除的實(shí)現(xiàn)...2006-08-08
SQL SERVER 數(shù)據(jù)庫(kù)備份的三種策略及語(yǔ)句
這篇文章主要介紹了SQL SERVER 數(shù)據(jù)庫(kù)備份的三種策略及語(yǔ)句,需要的朋友可以參考下2017-02-02
圖書管理系統(tǒng)的sqlserver數(shù)據(jù)庫(kù)設(shè)計(jì)示例
這篇文章主要介紹了圖書管理系統(tǒng)的sqlserver數(shù)據(jù)庫(kù)設(shè)計(jì)示例,文中通過(guò)E_R圖、數(shù)據(jù)字典、數(shù)據(jù)庫(kù)腳本代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
在數(shù)據(jù)庫(kù)中自動(dòng)生成編號(hào)的實(shí)現(xiàn)方法分享
一直很討厭存儲(chǔ)過(guò)程,沒想到今天幫了我大忙啊,或許會(huì)因?yàn)榻裉熳屛衣矚g上存儲(chǔ)過(guò)程吧,不多說(shuō)了,切入正題2011-10-10
asp.net中如何調(diào)用sql存儲(chǔ)過(guò)程實(shí)現(xiàn)分頁(yè)
使用sql存儲(chǔ)過(guò)程實(shí)現(xiàn)分頁(yè),在網(wǎng)上能找到好多種解決方案,但是如何用asp.net后臺(tái)調(diào)用呢,通過(guò)本篇文章小編給大家詳解asp.net中如何調(diào)用sql存儲(chǔ)過(guò)程實(shí)現(xiàn)分頁(yè),有需要的朋友可以來(lái)參考下2015-08-08

