触发器

来源:互联网 发布:淘宝助手是什么 编辑:程序博客网 时间:2024/06/04 23:19

基本概念

1.触发器的概念

触发器是在满足某个特定条件自动触发执行的专用存储过程,用于保证表中的数据遵循数据库设计者确定的规则和约束。触发器可以用SQL语句编写。与存储过程不同的是,存储过程是通过名称而被显式调用执行,而触发器是通过事件进行触发而被执行,不能被显式调用。如当对表进行更新(update),插入(insert),删除(delete)时,DBMS就会自动触发执行触发器所定义的SQL语句。
SQL Server中提供两种触发器:after触发器和instead of触发器。

2.触发器中的两个特殊表

inserted和deleted表。这两个表存储在缓存中,由系统维护,不允许用户对其修改。

(1)inserted表。该表中存放的是由于执行insertupdate语句而要向表中插入的新数据行。当用户执行insertupdate时,新的数据行被添加到激活触发器的表中,同时这些数据行的备份被复制到insertd临时表中。(2)deleted表。该表中存放的是由于执行deleteupdate语句而要从表中删除的数据行。在执行deleteupdate语句时,指定的数据行被用户从基本表中删除,然后被转移到了deleted表中。一般来说,在基本表和deleted表中不会存在有相同的数据行。   对于表的更新操作update,可以看作是由两个操作组成的。首先将旧的数据行从基本表中转移到deleted表中,即执行一个delete操作;然后将新的数据行同时插入到激活触发器的基本表和inserted表中。

定义触发器

1.使用SQL语句创建触发器

create trigger trigger_name on {table_name | view_name}[with encryption] {for | after | instead of}[insert,update,delete]as  sql_statement其中trigger_name:用户创建的触发器的名称。触发器名称必须符合标识符规则,并且在数据库中必须唯一。table_name | view_name:在其上定义触发器的表或视图名称,也称为触发器表或触发器视图with encryption:加密syscomments表中包含的create trigger语句文本。after:指定触发器的激活时机是在触发SQL语句中指定的操作都已成功执行后。一个表的每个修改动作均可有多个after触发器。注意,不能在视图上定义after触发器。for:与after相同,为兼容早期的SQL Server版本而设置。instead of:指定执行触发器中的SQL语句而不执行触发SQL语句,从而代替触发语句的操作。在表或视图上,每个insert,update,delete语句最多可以定义一个instead of触发器。instead of触发器不能再使用了with check option选项的可更新视图上定义。sql_statement:触发器被触发后要执行的SQL语句。

eg:创建一个触发器,当学生表中的记录被更新时,显示表中的所有记录。

create trigger student_change   on student after insert,update,delete   as      select * from student;

eg:在Student表上创建delete触发器,实现Student表和SC表的级联删除。

create trigger studentDelete on Student       after deleteas       delete from SC       where Son in(select deleted.Sno from deleted);

eg:在SC表上创建insert触发器,当向SC表中添加学生的选课记录时,检查该学生的Sno是否存在。若不存在,则不能将记录插入。

create trigger sc_insert on SC   after insertas   if(select count(*) from Student,inserted     where Student.Sno=inserted.Sno)=0   begin     print '学号不存在,不能插入该记录'     rollback transaction   end;在该触发器中,当向SC表中添加记录后,首先检查Sno在Student表中是否存在,若不存在,则事务回滚。

eg:创建update触发器,禁止对Student表中学生的学号进行修改

create trigger student_update on Student    after updateas    if update(Sno)    begin       print '学生的学号不能修改'       rollback transaction    end;

eg:在SC表上创建触发器,当一次向SC表中添加多个记录时,删除学号在Student表中不存在的记录,从而保证数据的一致性。注意,不能在SC表中定义外键约束。

create trigger sc_insert on SC after insertas  if(select count(*)    from Student,inserted    where Student.Sno=inserted.Sno)<> @@rowcount  begin    delete from SC    where Sno not in(select Sno from Student)  end;在该触发器被激活以前,insert操作已经把所有记录插入到SC表中了,这些记录可能包含学号在Student表中不存在的记录。当该触发器被激活后,判断插入到SC表的Sno是否都在Student表中存在。若有不存在的,则从SC表中删除那些Sno在Student表中不存在的记录。

eg:在视图上定义instead of触发器。

假设有一个反映学生出生年份的视图create view birth_view(Sno,Sname,Ssex,Sbirth,Sdept)as  select Sno,Sname,Ssex,2008-Sage,Sdept  from student;

在该视图中,学生的出生年份是通过计算得到的。若通过该视图向Student表中插入一条记录,例如(‘950021’,’李伟’,’男’,1987,’CS’),则可以在该视图上定义如下的instead of触发器来实现。

create trigger birth_view_insert on birth_viewinstead ofas    declare @Sno char(6)    declare @Sname varchar(10)    declare @Ssex char(2)    declare @birth int    declare @Sage int    declare @Sdept char(20)    select @Sno=Sno,@Sname=Sname,@Ssex=Ssex,@birth=Sbirth,@Sdept=Sdept    from inserted    set @Sage=2008-@birth    insert into Student(Sno,Sname,Ssex,Sage,Sdept)    values(@Sno,@Sname,@Ssex,@Sage,@Sdept);   instead of触发器用于替代引起触发器执行的SQL语句。当向birth_view视图执行insert语句时,birth_view_insert触发器激活,此时inserted表中已经有了要插入的数据,如('950021','李伟','男',1987,'CS')。在birth_view_insert触发器代码中,计算@Sage=2008-@birth,然后将数据插入基本表Student中,而激发该触发器的insert语句不会被执行。    例如,在birth_view视图执行插入语句    insert into birth_view    values('950021','李伟','男',1987,'CS');    则可以将该记录插入到表Student中。

删除触发器

drop trigger trigger_name[,...n];

相关链接:http://www.cnblogs.com/rainman/p/3675834.html

原创粉丝点击