Sql Server 触发器

⒈是什么?

  触发器是一种特殊类型的存储过程,触发器主要是通过事件进行触发被自动调用执行,而存储过程可以通过存储过程的名称被调用。

  当我们对某张表进行操作(例如增删改)时会自动调用执行该表上对应的触发器。

  SQL Server 中触发器可以分为两类:DML触发器和DDL触发器,其中DDL触发器它们会影响多种数据定义语言语句而激发,这些语句有create、alter、drop语句。

    DML触发器分为:

    1、 after触发器(之后触发)

        a、 insert触发器

        b、 update触发器

        c、 delete触发器

    2、 instead of 触发器 (之前触发)

  after触发器要求只有当我们对某张表进行操作(例如增删改)时才会自动调用执行该表上对应的after触发器,且只能定义在表上。

  instead of触发器并不执行其定义的操作(insert、update、delete)而仅是执行触发器本身,既可以在表上定义instead of触发器,也可以在视图上定义。

   触发器有两张特殊的表:插入表(instered表)和删除表(deleted表)。这两张是逻辑表也是虚表。系统会在内存中创建这两张表,不会存储在数据库中。且这两张表的都是只读的,只能读取数据而不能修改数据。这两张表的结果总是与被改触发器应用的表的结构相同。当触发器完成工作后,这两张表就会自动被删除。Inserted表的数据是插入或是修改后的数据,而deleted表的数据是更新前的或是删除的数据。

 

 

对表的操作

Inserted逻辑表

Deleted逻辑表

增加记录(insert)

存放增加的记录

删除记录(delete)

存放被删除的记录

修改记录(update)

存放更新后的记录

存放更新前的记录

 

    Update数据的时候就是先删除表记录,然后增加一条记录。这样在inserted和deleted表就都有update后的数据记录了。注意的是:触发器本身就是一个事务,所以在触发器里面可以对修改数据进行一些特殊的检查。如果不满足可以利用事务回滚,撤销操作。

⒉创建触发器

  1.after触发器(之后触发)

    ①语法

1 create trigger tgr_name on tableName
2 with encryption    --加密触发器
3 for update
4 as
5     sql
6 go

    ②示例

      Ⅰinsert类型触发器

 1 if(OBJECT_ID('tgr_users_insert','tr') is not null)
 2 drop trigger tgr_users_insert
 3 go
 4 create trigger tgr_users_insert on users
 5 for insert --插入时触发
 6 as
 7     declare @id int,@username varchar(20);
 8     select @id = id,@username = username from inserted; --inserted虚拟表中存放了新插入的那条数据
 9     select concat('新用户的Id是:',@id,',新用户的用户名是:',@username);
10 go

      Ⅱdelete类型触发器

 1 if(OBJECT_ID('tgr_users_delete','tr') is not null)
 2 drop trigger tgr_users_delete
 3 go
 4 create trigger tgr_users_delete on users
 5 for delete    --删除时触发
 6 as
 7     declare @id int,@username varchar(20);
 8     select @id = id,@username = username from deleted; --deleted虚拟表中存放了删除的那条数据
 9     select concat('删除用户的Id是:',@id,',删除用户的用户名是:',@username);
10 go

      Ⅲupdate类型触发器

 1 if(OBJECT_ID('tgr_users_update','tr') is not null)
 2 drop trigger tgr_users_update
 3 go
 4 create trigger tgr_users_update on users
 5 for update    --更新时触发
 6 as
 7     declare @id int,@oldusername varchar(20),@newusername varchar(20);
 8     select @id = id,@oldusername = username from deleted; --deleted虚拟表中存放了更新前的那条数据
 9     select @newusername = username from inserted;    --inserted虚拟表中存放了更新后的那条数据
10     select concat('更新用户的Id是:',@id,',更新前用户名是:',@oldusername,',更新后用户名是:',@newusername);
11 go

      Ⅳupdate列级触发器

 1 if(OBJECT_ID('tgr_users_update_column','tr') is not null)
 2 drop trigger tgr_users_update_column
 3 go
 4 create trigger tgr_users_update_column on users
 5 for update    --更新时触发
 6 as
 7     if(update(username))
 8     begin
 9         raisError('用户名禁止修改!',16,11);
10         rollback tran;
11     end
12 go

  2.instead of 触发器 (之前触发)

  instead of触发器表示并不执行其定义的操作(insert、update、delete)而仅是执行触发器本身的内容。

    ①语法

1 create trigger tgr_name on tableName
2 with encryption    --加密触发器
3 instead of update
4 as
5     sql
6 go

    ②示例

      Ⅰinstead of触发器

 1 if(OBJECT_ID('tgr_users_insteadof','tr') is not null)
 2 drop trigger tgr_users_insteadof
 3 go
 4 create trigger tgr_users_insteadof on users
 5 instead of delete --update, insert..
 6 as
 7     declare @id int,@username varchar(20);
 8     select @id = id , @username = username from deleted;
 9     select concat('删除用户的Id是:',@id,',删除用户的用户名是:',@username);
10 go

      Ⅱ显示自定义消息raiserror

1 if (OBJECT_ID('tgr_message', 'TR') is not null)
2     drop trigger tgr_message
3 go
4 create trigger tgr_message on users
5 after insert, update
6 as 
7     raisError('tgr_message触发器被触发', 16, 10);
8 go

⒊修改触发器

1 alter trigger tgr_message on users
2 after delete
3 as raisError('tgr_message触发器被触发', 16, 10);
4 go

⒋启用/禁止触发器

1 --禁用触发器
2 disable trigger tgr_message on users;
3 --启用触发器
4 enable trigger tgr_message on users;

⒌查询触发器信息

 1 --查询已存在的触发器
 2 select * from sys.triggers;
 3 select * from sys.objects where type = 'TR';
 4 
 5 --查看触发器触发事件
 6 select te.* from sys.trigger_events te join sys.triggers t
 7 on t.object_id = te.object_id
 8 where t.parent_class = 0 and t.name = 'tgr_valid_data';
 9 
10 --查看创建触发器语句
11 exec sp_helptext 'tgr_message';

⒍附加

  1.验证数据

 1 if ((object_id('tgr_valid_data', 'TR') is not null))
 2     drop trigger tgr_valid_data
 3 go
 4 create trigger tgr_valid_data
 5 on student
 6 after insert
 7 as
 8     declare @age int,
 9             @name varchar(20);
10     select @name = s.name, @age = s.age from inserted s;
11     if (@age < 18)
12     begin
13         raisError('插入新数据的age有问题', 16, 1);
14         rollback tran;
15     end
16 go

  2.操作日志

 1 if (object_id('log', 'U') is not null)
 2     drop table log
 3 go
 4 create table log(
 5     id int identity(1, 1) primary key,
 6     action varchar(20),
 7     createDate datetime default getDate()
 8 )
 9 go
10 if (exists (select * from sys.objects where name = 'tgr_student_log'))
11     drop trigger tgr_student_log
12 go
13 create trigger tgr_student_log
14 on student
15 after insert, update, delete
16 as
17     if ((exists (select 1 from inserted)) and (exists (select 1 from deleted)))
18     begin
19         insert into log(action) values('updated');
20     end
21     else if (exists (select 1 from inserted) and not exists (select 1 from deleted))
22     begin
23         insert into log(action) values('inserted');
24     end
25     else if (not exists (select 1 from inserted) and exists (select 1 from deleted))
26     begin
27         insert into log(action) values('deleted');
28     end
29 go

 

原文地址,http://www.cnblogs.com/hoojo/archive/2011/07/20/2111316.html,在原作者基础上进行简化及修改。

 

posted @ 2019-04-27 21:36  SpringCore  阅读(274)  评论(0编辑  收藏  举报