sql server 觸發器

觸發器是一種特殊類型的存儲過程。觸發器可包含複雜的T-SQL語句。觸發器不能通過名稱被直接調用,也不允許設置參數。它是建立在觸發事件上的。
 
觸發器可以強制執行一定的業務規則,以保持數據完整性、檢查數據有效性、實現數據庫管理任務和一些附加功能。
 
觸發器的分類: DML、 DDL、 登錄觸發器
 
 
創建觸發器需要指定的選項:
 
 1.觸發器的名稱。
 2.在其上定義觸發器的表。
 3.觸發器將何時激發。
 4.激活觸發器的數據修改語句。
 5.執行觸發操作的編程語句。
 
 
CREATE TRIGGER語句基本語法格式如下:
 

CREATE TRIGGER     觸發器名稱

ON {表名 | 視圖名}

[with encryption]

{

   { {FOR | AFTER | INSTEAD OF}

   {[DELETE] [,][INSERT] [,] [UPDATE]}

   AS

   sql_statement […n ]

 

其中:

AFTER

指定觸發器只有在觸發 SQL 語句中指定的所有操作都已成功執行後才激發。所有的引用級聯操作和約束檢查也必須成功完成後,才能執行此觸發器。如果僅指定 FOR 關鍵字,則 AFTER 是默認設置。

INSTEAD OF

指定執行觸發器而不是執行觸發 SQL 語句,從而替代觸發語句的操作。

/*在student表上創建觸發器,
在用戶插入、修改和刪除記錄時,都會自動顯示錶中的內容:*/

use test
go

create trigger trig_1 on student
after insert,delete,update
as 
begin
    set nocount on
    select * from student
end

insert student(sno) values(5)

delete student where sno=5


exec sp_helptext trig_1    --查看觸發器內容 
exec sp_helptrigger student   --查看錶上的觸發器的屬性
select * from sysobjects where xtype='TR'  --查看數據庫中已有的觸發器


drop trigger trig_1


inserted表和deleted表

 
觸發器執行的時候,產生兩個臨時表:inserted表deleted表。它們的結構和所在的表的結構相同,可使用這兩個表測試某些數據修改的效果和設置觸發器操作的條件,但不能對錶中的數據進行更改。
deleted表用於存儲DELETE和UPDATE語句所影響的行的副本。在執行delete或update語句時,行從觸發器表中刪除,並傳輸到deleted表中。
inserted表用於存儲INSERT和UPDATE語句所影響的行的副本。在插入和更新時,新建行被同時添加到inserted表和觸發器表中。Inserted表中的行是觸發器表中新行的副本。
 
在對具有觸發器的表(觸發器表)進行操作時,有:
執行INSERT操作,插入到觸發器表中的新行被插入到inserted表中。
執行DELETE操作,從觸發器表中刪除的行被插入到deleted表中。
執行UPDATE操作,先從觸發器表中刪除舊行,然後再插入新行。刪除的舊行插入到deleted表中;更改後的新行被插入到inserted 表中。
 
 
 
使用DML觸發器
 
1. INSERT和UPDATE觸發器

     當向表中插入或者更新記錄時,INSERT或者UPDATE觸發器被激活。一般情況下,這兩種觸發器常用來檢查插入或者修改後的數據是否滿足要求。 

INSERT觸發器被觸發時,新的記錄增加到觸發器的對應表中,並且同時也添加到一個inserted表中。
修改一個記錄等於插入了一個新的記錄並且刪除一箇舊的記錄。當在一個有UPDATE觸發器的表中修改記錄時,表中原來的記錄被移動到deleted表中,修改過的記錄插入到了插入表中,觸發器可以參考deleted表和inserted表以及被修改的表,以確定如何完成數據庫操作。
 
2. DELETE觸發器
DELETE觸發器通常用於下面的情況:
防止那些確實要刪除,但是可能會引起數據一致性問題的情況,一般是用於那些用作其他表的外部鍵記錄。
用於級聯刪除操作。
 
例如:
/*例:下例說明inserted表和deleted表的作用*/

if exists(select name from sysobjects where name='trig_2' and type='TR')
    drop trigger trig_2
go

create trigger trig_2 
on student
after update                         --update觸發器
as 
    print 'inserted表'
    select * from inserted
    print 'deleted表'
    select * from deleted
go
set nocount on
update student set sname='關二' where sno=2
--drop trigger trig_2


create trigger trig_3 
on student
after insert                         --insert觸發器
as 
    print 'inserted表'
    select * from inserted
    print 'deleted表'
    select * from deleted
go
insert student values(100,'劉一百','男',25)
drop trigger trig_3


create trigger trig_4 
on student
after delete                         --delete觸發器
as 
    print 'inserted表'
    select * from inserted
    print 'deleted表'
    select * from deleted
go
delete student where sno=100
drop trigger trig_4

修改觸發器
 
語法格式:

ALTER TRIGGER trigger_name

ON ( table | view )

{

  { ( FOR | AFTER | INSTEAD OF ) }

  { [ DELETE ] [ , ] [ INSERT ] [ , ] [ UPDATE ] }

AS

  sql_statement […n ]

  }   

 

DDL觸發器使用

 

例如:

/*DDL觸發器*/

/*在test數據庫上創建一個DDL觸發器safe,
用來防止數據庫中的任一表被修改或刪除。*/

create trigger safetest
on database                         --數據庫DDL觸發器
after drop_table,alter_table
as
begin
    raiserror('不能修改表結構',16,2)
    rollback
end
go
 
--執行以下程序,觀察結果
alter table student add nation char(10)

disable trigger safetest on database
drop trigger safetest on database
---------------------------------------------------------


/*在服務器上創建一個DDL觸發器tablecreat,
用來防止在服務器上創建數據庫*/

create trigger trig_last
on all server
after create_database
as
begin
    raiserror('不能創建新的數據庫',16,2)
    rollback
end
go

--執行以下程序,觀察結果
create database test_trig

disable trigger trig_last on all server
drop trigger trig_last on all server

刪除觸發器

 
使用SQL Server Management Studio刪除觸發器
使用DROP TRIGGER語句來刪除觸發器。其語法格式如下:

DROP TRIGGER { trigger } [ , …n ]

 

觸發器禁用和啓用

 

例如:

/*觸發器禁用和啓用*/

/*禁用sc表上的觸發器trig_g。*/
alter table sc disable trigger trig_g
disable trigger trig_g on sc
go

/*啓用sc表上的觸發器trig_g。*/
alter table sc enable trigger trig_g
enable trigger trig_g on sc
go

--執行以下程序,觀察結果
insert into sc values(1,100,1,-50)
select * from sc

觸發器具體應用

 

例如:

/*具體應用*/

/*創建觸發器trig3,
當刪除student表中的學生記錄時,
應該同時刪除sc表中對應的記錄*/

create trigger trig_5
on student
for delete
as 
 delete sc
 where sc.sno in(select sno from deleted)
go

select * from student
select * from sc
go

/*exec sp_help score   --查看其中外鍵

alter table score         --刪除外鍵
drop CONSTRAINT FK_score_course

alter table score
drop CONSTRAINT FK_score_student*/


delete student where sno=3
go

select * from student
select * from sc 
-------------------------------------------------------------


create trigger trig_g 
on sc
after insert,update
as
begin
    declare @g int
    select @g=grade from inserted
    if @g<0
    begin
         select '成績必須>=0'
         rollback
    end
end
go

--執行以下程序,觀察結果
insert into sc values(1,10,1,50)
select * from sc


/*例: 建立一個修改觸發器trigno,
該觸發器防止用戶修改表student的學號*/

create trigger trigno
on student
after update
as
if update(sno)
    begin
        raiserror('不能修改學號',16,2)
        rollback
    end
go

--執行以下程序,觀察結果
update student set sno='2' where sno='1'
select * from student
------------------------------------------------------


/*INSTEAD OF觸發器*/

/*例:在student表上創建一個INSTEAD OF觸發器trig_6,
當用戶插入數據時注意觀察觸發器的執行。*/

create trigger trig_6
on student
instead of insert
as
    select * from student
go

--執行以下程序,觀察結果
insert into student(sno,sname) values('300','白扯')

博客園博客:欠扁的小籃子
發佈了82 篇原創文章 · 獲贊 101 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章