SQL Server 触发器
触发器
触发器是一种特殊类型的存储过程,它在您使用一种或多种数据修改操作(UPDATE、INSERT 或 DELETE)来修改指定表中的数据时运行。
触发器分类
DML触发器和DDL触发器,其中
DML触发器分为:
1、 after触发器(之后触发)
a、 insert触发器
b、 update触发器
c、 delete触发器
2、 instead of 触发器 (之前触发)
数据操作与逻辑表间关系
|
新增 |
更新 |
删除 |
inserted(后) |
√ |
√ |
|
deleted(前) |
|
√ |
√ |
以下实例可以体现上述关系(代码来自:SQL Server 触发器):
if (object_id('log', 'U') is not null) drop table log go create table log( id int identity(1, 1) primary key, action varchar(20), createDate datetime default getDate() ) go if (exists (select * from sys.objects where name = 'tgr_student_log')) drop trigger tgr_student_log go create trigger tgr_student_log on student after insert, update, delete as if ((exists (select 1 from inserted)) and (exists (select 1 from deleted))) begin insert into log(action) values('updated'); end else if (exists (select 1 from inserted) and not exists (select 1 from deleted)) begin insert into log(action) values('inserted'); end else if (not exists (select 1 from inserted) and exists (select 1 from deleted)) 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;
注:Update数据的时候就是先删除表记录,然后增加一条记录。这样在inserted和deleted表就都有update后的数据记录了。注意的是:触发器本身就是一个事务,所以在触发器里面可以对修改数据进行一些特殊的检查。如果不满足可以利用事务回滚,撤销操作。
查询创建的触发器信息
--查询已存在的触发器 select * from sys.triggers; select * from sys.objects where type = 'TR'; --查看触发器触发事件 select te.* from sys.trigger_events te join sys.triggers t on t.object_id = te.object_id where t.parent_class = 0 and t.name = 'tgr_valid_data'; --查看创建触发器语句 exec sp_helptext 'tgr_message';
启用、禁用触发器
--禁用触发器 disable trigger tgr_message on student;
alter table student disable trigger tgr_message
--启用触发器
enable trigger tgr_message on student;
alter table student enable trigger tgr_message
--禁用某个表上的所有触发器
ALTER TABLE 你的表 DISABLE TRIGGER all
--启用某个表上的所有触发器
ALTER TABLE 你的表 enable TRIGGER all
--禁用所有表上的所有触发器
exec sp_msforeachtable 'ALTER TABLE ? DISABLE TRIGGER all'
--启用所有表上的所有触发器
exec sp_msforeachtable 'ALTER TABLE ? enable TRIGGER all'
事务回滚,撤销操作
if ((object_id('tgr_valid_data', 'TR') is not null)) drop trigger tgr_valid_data go create trigger tgr_valid_data on student after insert as declare @age int, @name varchar(20); select @name = s.name, @age = s.age from inserted s; if (@age < 18) begin raisError('插入新数据的age有问题', 16, 1); rollback tran; end go --test insert into student values('forest', 2, 0, 7); insert into student values('forest', 22, 0, 7); select * from student order by id;
创建instead of触发器
instead of触发器表示并不执行其定义的操作(insert、update、delete)而仅是执行触发器本身的内容。
比如删除主表数据之前要先删除从表的时候,可以在主表建立instead of delte触发器。
if (object_id('tgr_classes_inteadOf', 'TR') is not null) drop trigger tgr_classes_inteadOf go create trigger tgr_classes_inteadOf on classes instead of delete/*, update, insert*/ as declare @id int, @name varchar(20); --查询被删除的信息,病赋值 select @id = id, @name = name from deleted; print 'id: ' + convert(varchar, @id) + ', name: ' + @name; --先删除student的信息 delete student where cid = @id; --再删除classes的信息 delete classes where id = @id; print '删除[ id: ' + convert(varchar, @id) + ', name: ' + @name + ' ] 的信息成功!'; go
以上整理大部分剽窃自:http://www.cnblogs.com/hoojo/archive/2011/07/20/2111316.html