觸發器對錶進行插入、更新、刪除的時候會自動執行的特殊預存程序。觸發器一般用在check約束更複雜的約束上面。觸發器和普通的預存程序的區別是:觸發器是當對某一個表進行操作時。諸如:update、insert、delete這些操作的時候,系統會自動呼叫執行該表上對應的觸發器。 SQL Server 2005中觸發器可以分為兩類:DML觸發器和DDL觸發器,其中DDL觸發器它們會影響多種資料定義語言語句而激發,這些語句有create、alter、drop語句。
常見的觸發器有三種:分別應用於Insert , Update , Delete 事件。
我為什麼要使用觸發器?例如,如此兩張表:
Create Table Student( -- ....
)
Create Table BorrowRecord( BorrowRecord int identity(1,1), --流水號
...
)
所使用的功能有:
1.如果我更改了學生的學號,我希望他的借書記錄仍然與這個學生相關(也就是同時更改借書記錄表的學號);
2.如果該學生已經畢業,我如果該學生已經畢業,我希望刪除他的學號的同時,也刪除它的借書紀錄。
等等。
這時候可以用到觸發器。對於1,建立一個Update觸發器:
On Student
for Update --所要做的事if Update (StudentID)
begin
Update BorrowRecord
Set StudentID=i.StudentID
From BorrowRecord br , Deleted d ,Inserted i --Deleted和Inserted臨時表
Where br.StudentID=d.StudentID
理解觸發器裡面的兩個臨時的表:Deleted , Inserted 。注意Deleted 與Inserted分別表示觸發事件的表格「舊的一筆記錄」與「新的一筆記錄」。
一個資料庫教學系統中有兩個虛擬表用於儲存表中記錄變更的資訊,分別是:
虛擬表Deleted
在表記錄新增時 儲存新增的記錄 修改時 存放用來更新的新紀錄 儲存刪除的記錄
2,創建一個Delete觸發器
Create trigger trdStudent Delete BorrowRecord
From BorrowRecord br , Delted d
個例子我們可以看到了觸發器的關鍵:A.2個臨時的表;B.觸發機制
DML觸發器分為:
1、after觸發器(之後觸發)
b、 update觸發器
c、 delete觸發器
只有執行某一操作insert、update、delete之後觸發器才被觸發,只能定義在表上。而instead of觸發器表示並不執行其定義的操作(insert、update、delete)而僅是執行觸發器本身。既可以在表上定義instead of觸發器,也可以在視圖上定義。 觸發器有兩個特殊的表:插入表(instered表)和刪除表(deleted表)。這兩張是邏輯表也是虛表。有系統在記憶體中創建者兩張表,不會儲存在資料庫中。而且兩張表的都是唯讀的,只能讀取資料而不能修改資料。這兩張表的結果總是與被改觸發器所應用的表的結構相同。當觸發器完成工作後,這兩張表就會被刪除。 Inserted表的數據是插入或是修改後的數據,而deleted表的數據是更新前的或是刪除的數據。
Update資料的時候就是先刪除表格記錄,然後再增加一筆記錄。這樣在inserted和deleted表就都有update後的資料記錄了。注意的是:觸發器本身就是一個事務,所以在觸發器裡面可以對修改資料進行一些特殊的檢查。如果不滿足可以利用交易回滾,撤銷操作。
Ø 建立觸發器
語法
create trigger tgr_nameon table_name
with encrypion – 觸發 # 建立insert類型觸發器--建立insert插入類型觸發器
if (object_id('tgr_classes_insert', 'tr') is not null)
drop trigger tgr_classes_insert
go
create trigger tgr_class_class_classes_insert
- -定義變數
declare @id int, @name varchar(20), @temp int;
--在inserted表中查詢已插入記錄資訊
select @id = id, @name = name from fromtedname; = @name + convert(varchar, @id);
set @temp = @id / 2;
insert into student values(@name, 18 + @id, @temp, @id); ';
go
--插入資料
insert into classes values('5班', getDate());
--查詢資料
select * from classes;
select * from student order by id;
ins ,會在inserted表中新增一筆剛插入的記錄。
# 建立delete型別觸發器
--delete刪除型別觸發器
if (object_id('tgr_classes_delete', 'cate es_deleteon classes
for delete --刪除觸發as
print '備份資料中…'; if (object_id('classesBackup', 'U') is not null)
Backup select name , createDate from deleted;
else
--不存在classesBackup建立再插入
select * into classesBackup from deleted;🎠備份資料成功! ';
go
--
--不顯示影響行數
--set nocount on;
delete classes where name = '5班';
--查詢資料
select * from classes;
select * from classesB--查詢資料
select * from classes;
seackup;
delete觸發器會在刪除資料的時候,將剛才刪除的資料保存在deleted表中。
# 建立update型別觸發器
--update更新型別觸發器
if (object_id('tgr_classes_update', 'TR') is not nullrigdate gr tgr_classes_update
for update
asdeclare @oldName varchar(20), @newName varchar(20);
--更新前的資料select @oldName = name from deleted; '+ @oldName + '%'))
begin --更新後的資料
= replace(name, @oldName, @newName) where name like '%' + @oldName + '%';
print '級聯修改資料成功! ';
end
else
print '無修改student手錶! ';
go
--查詢資料
select * from student order by id;
select * from classes;
update classes set name = '五班' where name = '5班';資料後,將更新前的資料保存在inserted表中,更新後的資料保存在inserted表中。
# update更新列級觸發器
if (object_id('tgr_classes_update_column', 'TR') is not null)
classes_update_column
on classes
for update
as
--列級觸發器:是否更新了班級創建時間
if (update(createDate))
begin
raisError('系統提示:
--測試
select * from student order by id;select * from classes;
update classes set createDate = getDate() where id = 3;update classes set name = '四班';列級觸發器可以用update是否判斷更新列記錄;
# instead of類型觸發器
instead of觸發器表示不執行其定義的操作僅是執行其定義的操作(insert、update、delete.本身的內容。
建立文法
create trigger tgr_name
on table_name
with encryption
instead of update...
as
T-SQL
drop trigger tgr_classes_inteadOf
gocreate trigger tgr_classes_inteadOf
on classes instead of delete/*, update, classes
instead of delete/*, update, 類
--查詢被刪除的信息,病賦值
select @id = id, @name = name from deleted;
print 'id: ' + convert(varchar, @id) + ', name: ' + @name;
--先刪除student的資訊
ete student where cid = @id;
--再刪除classes的訊息
delete classes where id = @id;
print '刪除[ id: ' + convert(varchar, @id) + ', name: ' + @name + ' ] 的訊息成功! ';
go
--test
select * from student order by id;
select * from classes;
delete classes where id = 7;
_raoion sage' , 'TR') is not null)
drop trigger tgr_message
go
create trigger tgr_message
after insert, update
on studentafter insert, update
, 11,005,000,000 messmdate', 1,005,000mess);
--test
insert into student values('lily', 22, 1, 7);
update student set sex = 0 where name = 'lucy';
select * from student order by id;
夾修改器修改器tgr_message
on student
after delete
as raisError('tgr_message觸發器被觸發', 16, 10);
go
--test
--test
delete from student where name = 'go--test
delete from student where name = '';啟用器
--停用觸發器
disable trigger tgr_message on student;
--啟用觸發器
enable trigger tgr_message on student;
. .triggers;
select * from sys.objects where type = 'TR';
--查看觸發器觸發事件
select te.* from sys.trigger_events te join sys.triggers t
on t.object_object.
exec sp_helptext 'tgr_message';
tgr_valid_data', 'TR') is not null))
drop trigger tgr_valid_data
go
create trigger tgr_valid_data
on student
@name varchar(20);
select @name = s .name, @age = s.age from inserted s;
if (@age begin
raisError('為插入新資料的age
--test
insert into student values('forest', 2, 0, 7);insert into student values('forest', 22, 0, 7);
select * from student order by id;🎠 範例,作業日誌
if (object_id('log', 'U') is not null)
drop table log
go
create table log(
id int identity
create table log(
id int identity(1, 1) ,
createDate datetime default getDate()
)
go
if (exists (select * from sys.objects where name = 'tgr_student_log'))
名詞
on student
after insert, update, delete
as
if ((exists (select 1 from inserted)) and (exists (select 1 from deleted)))
begin
insert in log(action) value se if (exists ( select 1 from inserted) and not exists (select 1 from deleted))
begin
begin
insert into log(action) values('deleted'); end
go
--test
insert into student values('king', 22, 1, 7);
update student set sex = 0 where name = 'king';
delete student where name = 'king';
select * from log;
select * from student order by id;