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

 

posted @ 2017-06-02 13:21  自由的鱼  阅读(186)  评论(0编辑  收藏  举报