概念:
觸發器(trigger)是SQLserver提供給程序員和數據分析員來保證數據完整性的一種方法,它是與表事件相關的特殊的存儲過程,它的執行不是由程序調用,也不是手工啟動,而是由事件來觸發,當對一個表進行操作(insert,delete,update)時就會激活它執行。觸發器經常用于加強數據的完整性約束和業務規則等。觸發器可以從DBA_TRIGGERS,USER_TRIGGERS數據字典中查到。
觸發器和存儲過程的區別:
觸發器與存儲過程的區別是運行方式的不同,觸發器不能執行EXECUTE語句調用,而是在用戶執行Transact-SQL語句時自動觸發執行而存儲過程需要用戶,應用程序或者觸發器來顯示地調用并執行。
一:觸發器的優點1.觸發器是自動的。當對表中的數據做了任何修改之后立即被激活。
2.觸發器可以通過數據庫中的相關表進行層疊修改。
3.觸發器可以強制限制。這些限制比用CHECK約束所定義的更復雜。與CHECK約束不同的是,觸發器可以引用其他表中的列。
二:觸發器的作用觸發器的主要作用就是其能夠實現由主鍵和外鍵所不能保證的復雜參照完整性和數據的一致性,它能夠對數據庫中的相關表進行級聯修改,提高比CHECK約束更復雜的的數據完整性,并自定義錯誤消息。觸發器的主要作用主要有以下接個方面:
SqlServer包括三種常規類型的觸發器:DML觸發器、DDL觸發器和登錄觸發器。
1.DML(數據操作語言,DataManipulationLanguage)觸發器
DML觸發器是一些附加在特定表或視圖上的操作代碼,當數據庫服務器中發生數據操作語言事件時執行這些操作。SqlServer中的DML觸發器有三種:
當遇到下列情形時,應考慮使用DML觸發器:
2.DDL(數據定義語言,DataDefinitionLanguage)觸發器
DDL觸發器是當服務器或者數據庫中發生數據定義語言(主要是以create,drop,alter開頭的語句)事件時被激活使用,使用DDL觸發器可以防止對數據架構進行的某些更改或記錄數據中的更改或事件操作。
3.登錄觸發器
登錄觸發器將為響應LOGIN事件而激發存儲過程。與SQLServer實例建立用戶會話時將引發此事件。登錄觸發器將在登錄的身份驗證階段完成之后且用戶會話實際建立之前激發。因此,來自觸發器內部且通常將到達用戶的所有消息(例如錯誤消息和來自PRINT語句的消息)會傳送到SQLServer錯誤日志。如果身份驗證失敗,將不激發登錄觸發器。
四:觸發器的工作原理觸發器觸發時:
inserted表:
deleted表:
inserted表和deleted表對照:
修改操作記錄 | inserted表 | deleted表 |
增加(insert)記錄 | 存放新增的記錄 | ............ |
刪除(deleted)記錄 | .............. | 存放被刪除的記錄 |
修改(update)記錄 | 存放更新后的記錄 | 存放更新前的記錄 |
創建觸發器的語法:
CREATE TRIGGER trigger_name ON table_name [WITH ENCRYPTION] FOR | AFTER | INSTEAD OF [DELETE, INSERT, UPDATE] AS T-SQL語句GO--with encryption 表示加密觸發器定義的sql文本--delete,insert,update指定觸發器的類型
準備測試數據:
--創建學生表create table student( stu_id int identity(1,1) primary key, stu_name varchar(10), stu_gender char(2), stu_age int)
1.創建insert觸發器
--創建insert觸發器create trigger trig_inserton studentafter insertasbegin if object_id(N'student_sum',N'U') is null--判斷student_sum表是否存在 create table student_sum(stuCount int default(0));--創建存儲學生人數的student_sum表 declare @stuNumber int; select @stuNumber = count(*)from student; if not exists (select * from student_sum)--判斷表中是否有記錄 insert into student_sum values(0); update student_sum set stuCount =@stuNumber; --把更新后總的學生數插入到student_sum表中end
--測試觸發器trig_insert-->功能是向student插入數據的同時級聯插入到student_sum表中,更新stuCount--因為是后觸發器,所以先插入數據后,才觸發觸發器trig_insert;insert into student(stu_name,stu_gender,stu_age)values('呂布','男',30);select stuCount 學生總人數 from student_sum; insert into student(stu_name,stu_gender,stu_age)values('貂蟬','女',30); select stuCount 學生總人數 from student_sum;insert into student(stu_name,stu_gender,stu_age)values('曹阿瞞','男',40); select stuCount 學生總人數 from student_sum;
執行上面的語句后,結果如下圖所示:
既然定義了學生總數表student_sum表是向student表中插入數據后才計算學生總數的,所以學生總數表應該禁止用戶向其中插入數據
--創建insert_forbidden,禁止用戶向student_sum表中插入數據create trigger insert_forbiddenon student_sumafter insertasbegin RAISERROR('禁止直接向該表中插入記錄,操作被禁止',1,1)--raiserror 是用于拋出一個錯誤rollback transactionend
--觸發觸發器insert_forbiddeninsert student_sum (stuCount) values(5);
結果如下:
2.創建delete觸發器
用戶執行delete操作,就會激活delete觸發器,從而控制用戶能夠從數據庫中刪除數據記錄,觸發delete觸發器后,用戶刪除的記錄會被添加到deleted表中,原來表的相應記錄被刪除,所以在deleted表中查看刪除的記錄。
--創建delete觸發器create trigger trig_deleteon student after deleteasbegin select stu_id as 已刪除的學生編號,stu_name stu_gender,stu_age from deletedend;
--執行一一條delete語句觸發trig_delete觸發器delete from student where stu_id=1;
結果如下:
3.創建UPDATE觸發器
update觸發器是當用戶在指定表上執行update語句時被調用被調用,這種類型的觸發器用來約束用戶對數據的修改。update觸發器可以執行兩種操作:更新前的記錄存儲在deleted表中,更新后的記錄存儲在inserted表中。
--創建update觸發器create trigger trig_updateon studentafter updateasbegin declare @stuCount int; select @stuCount=count(*) from student; update student_sum set stuCount =@stuCount; select stu_id as 更新前學生編號,stu_name as 更新前學生姓名 from deleted select stu_id as 更新后學生編號,stu_name as 更新后學生姓名 from insertedend
--創建完成,執行一條update語句觸發trig_update觸發器update student set stu_name='張飛' where stu_id=2;
4.創建替代觸發器
與前面介紹的三種after觸發器不同,SqlServer服務器在執行after觸發器的sql代碼后,先建立臨時的inserted表和deleted表,然后執行代碼中對數據庫操作,最后才激活觸發器中的代碼。而對于替代(instead of)觸發器,SqlServer服務器在執行觸發instead of 觸發器的代碼時,先建立臨時的inserted表和deleted表,然后直接觸發instead of觸發器,而拒絕執行用戶輸入的DML操作語句。
--創建instead of 觸發器 create trigger trig_insteadOfon student instead of insertas begin declare @stuAge int; select @stuAge=(select stu_age from inserted)if(@stuAge >120) select '插入年齡錯誤' as '失敗原因'end
創建完成,執行一條insert語句觸發觸發器trig_insteadOf
5.嵌套觸發器介紹
如果一個觸發器在執行操作時調用了另外一個觸發器,而這個觸發器又接著調用了下一個觸發器,那么就形成了嵌套觸發器。嵌套觸發器在安裝時就被啟用,但是可以使用系統存儲過程sp_configure禁用和重新啟用嵌套觸發器。
嵌套觸發器不一定要形成一個環,它可以T1->T2->T3...這樣一直觸發下去,最多允許嵌套32層。如果嵌套的次數超過限制,那么該觸發器將被終止,并回滾整個事務,使用嵌套觸發器需要注意以下幾點:
嵌套是用來保持整個數據庫的完整性的重要功能,但有時可能需要禁用嵌套,如果禁用了嵌套,那么修改一個觸發器的實現不會再觸發該表上的任何觸發器。在下述情況下,需要禁用嵌套觸發器:
使用下列語句禁用嵌套和再次啟用嵌套:
--禁用嵌套exce sp_configure 'nested triggers',0;--啟用嵌套exce sp_configure 'nested triggers',1;
6.遞歸觸發器
觸發器的遞歸是指一個觸發器從其內部再一次激活該觸發器,例如update操作激活的觸發器內部還有一條數據表的更新語句,那么這個更新語句就有可能激活這個觸發器本身,當然,這種遞歸的觸發器內部還會有判斷語句,只有一定情況下才會執行那個T_SQL語句,否則就成為無線調用的死循環了。
SqlServer中的遞歸觸發器包括兩種:直接遞歸和間接遞歸。
默認情況下,遞歸觸發器選項是禁用的。遞歸觸發器最多只能遞歸16層,如果遞歸中的第16個觸發器激活了第17個觸發器,則結果與發布的rol
新聞熱點
疑難解答