/*触发器是一种不带参数特殊的存储过程,有用户定义,数据库系统根据一定的条件自动执行*/ 

  --SQL触发器大体上可以分为4种] 

  --insert 触发器:在对表进行数据录入的时候触发 

  --delete 触发器:删除表中的数据的时候触发 

  --instead of 触发器:此类触发器创建在视图之上,用来替代相应的动作,比如delete,insert,update 

  --触发器的内部可以使用commit和rollback 

   

  create table emp 

  ( 

  eid int primary key, 

  ename varchar(10), 

  sal money 

  ) 

   

  create trigger in_tr 

  on emp for insert 

  as 

  begin 

   if (user='dbo') 

   begin 

   print 'dbo不能录入数据' 

   rollback tran 

   end 

  end 

  insert into emp values(1001,'rose',456) 

  --触发器的触发发生在事件发生之后 

  --在触发器中添加临时表可记录操作 

  --在连接符union的各语句只触发一次 

  --采用union对数据库的资源有利 

  --触发器的主要功能:对历史数据的审计 

  --语句级触发器:每语句触发;行级触发器:每改变一行触发 

   

  /*inserted逻辑表*/ 

  /*作用:insert动作发生的时候,数据首先会被放入此表中接着等待用户的命令, 

  如果用户回退事务,则清空此表的内容,如果用户提交事务,则把此表的数据永久写入数据库 

  */ 

  --逻辑表的结构和触发器表的结构完全相同,存在与内存中 

  select * into new from emp where 1>2 

  --触发器中: 

  create trigger in_tr 

  on emp for insert 

  as 

  begin 

   if (user='dbo') 

   begin 

   print 'dbo不能录入数据' 

   rollback tran 

   insert into new select * from inserted 

   end 

  end 

  insert into emp values(1001,'rose',456) 

  --逻辑表的数据将录入new 

  --用于记录用户插入影响的行数以及数据,是否用union都会记录正确 

  --各种约束优先于触发器 

  /*逻辑表deleted,当delete动作发生的时候,要删除的数据首先会被放在deleted逻辑表中, 

  接着等待用户提交或者回退的命令,如果用户提交,则清空deleted逻辑表中的数据,如果 

  用户回退,则把deleted逻辑表的数据放回原地,以保证数据的一致性 

  */ 

  alter trigger del_tr 

  on emp for delete 

  as 

  begin 

   if (user='dbo') 

   begin 

   print 'dbo不能录入数据' 

   rollback tran 

   end 

   insert into new select * from deleted 

  end 

  delete from emp 

  /*一个表可以创建多个不同类型的触发器,也可以创建多个同类型的触发器, 

  但当一个表上存在多个相同类型的触发器的时候,触发器的执行顺序没有定义*/ 

   

   

  /*update动作发生的时候,将要被更新的数据(历史数据)首先被放在inserted逻辑表中, 

  接着数据库系统等待用户提交或者回退的命令,如果用户提交,则清空deleted逻辑表中 

  的数据,把inserted逻辑表中的数据放回原地,update涉及到两张逻辑表 

  逻辑表的结构与触发器的结构完全相同 

  */ 

   

  /*instead of 触发器*/ 

  create view v 

  as select * from emp 

  create trigger tr_v_insert 

  on v instead of insert 

  as 

  begin 

   print'录入数据' 

  end 

  --视图上的此触发器出发之后,基表上的触发器不再执行 

  create trigger tr 

  on emp for insert 

  as 

  begin 

   print 'insert' 

  end 

  在instead of触发器中可以使用逻辑表 

   

  --示例 

  create table goods 

  ( 

  gid int primary key, 

  price money, 

  ) 

  create trigger tr 

  on goods for update 

  as 

  begin 

   if (update(gid)) 

   begin 

   print'主键不能更新!' 

   rollback 

   end 

   if (update(price)) 

   begin 

   print'价格可以更新' 

   commit 

   end 

  end 

  update goods set gid=1001