1. 概述

触发器是一种特殊的存储过程,它不能被显式地调用,而是在往表中插入记录﹑更新记录或者删除记录时被自动地激活。 所以触发器可以用来实现对表实施复杂的完整性约束。

2. 触发器的分类

SQL Server2000提供了两种触发器:“Instead of” 和“After” 触发器。

一个表或视图的每一个修改动作(Insert、Update和Delete)都可以有一个“Instead of” 触发器,一个表的每个修改动作都可以有多个“After”触发器。

2.1 “Instead of”触发器

  • “Instead of”触发器在执行真正“插入”之前被执行。除表之外,“Instead of” 触发器也可以用于视图,用来扩展视图可以支持的更新操作。
  • “Instead of”触发器会替代所要执行的SQL语句,言下之意就是所要执行SQL并不会“真正执行”
alter trigger trigger_学生_Deleteon 学生instead of Deleteasbegin  select 学号, 姓名 from deletedenddelete from 学生 where 学号 = 4 

2.2 “After”触发器

  • “After”触发器在Insert、Update或Deleted语句执行之后被触发。“After”触发器只能用于表。
  • “After”触发器主要用于表在修改后(insert、update或delete操作之后),来修改其他表

3. Inserted和Deleted表

SQL Server为每个触发器都创建了两个专用表:Inserted表和Deleted表。

  • 这两个表由系统来维护,它们存在于内存中而不是在数据库中,可以理解为一个虚拟的表。
  • 这两个表的结构总是与被该触发器作用的表的结构相同。
  • 触发器执行完成后,与该触发器相关的这两个表也被删除。
  • Deleted表存放由于执行Delete或Update语句而要从表中删除的所有行。
  • Inserted表存放由于执行Insert或Update语句而要向表中插入的所有行。

对表的操作 Inserted逻辑表 Deleted逻辑表
增加记录(insert) 存放增加的记录
删除记录(delete) 存放被删除的记录
修改记录(update) 存放更新后的记录 存放更新前的记录

4. 触发器的执行过程

  • 如果一个Insert﹑update或者delete语句违反了约束,那么这条SQL语句就没有执行成功,因此“After”触发器也不会被激活。
  • “Instead of” 触发器可以取代激发它的操作来执行。它在Inserted表和Deleted表刚刚建立,其它任何操作还没有发生时被执行。因为“Instead of” 触发器在约束之前执行,所以它可以对约束进行一些预处理。

5. 创建触发器

create trigger trigger_nameon {table_name|view_name}{After|Instead of} {insert|update|delete}as 相应T-SQL语句
alter trigger trigger_nameon {table_name|view_name}{After|Instead of} {insert|update|delete}as 相应T-SQL语句
drop trigger trigger_name

8.1 查看数据库中所有触发器

select * from sysobjects where xtype='TR'
exec sp_helptext '触发器名'

两张表:学生(学号 int, 姓名 varchar)、借书记录(学号 int, 图书编号 int)

实现功能:在删除学生表时,如果该学生仍有借书记录(未还)则不能删除

alter trigger trigger_学生_Deleteon 学生instead of Deleteasbegin  if not exists(select * from 借书记录, deleted where 借书记录.学号 = deleted.学号)    delete from 学生 where 学生.学号 in (select 学号 from deleted)end

10.1 在“订单”表中建立触发器,当向“订单”表中插入一条订单记录时,检查“商品”表的货品状态“状态”是否为1(正在整理),则不能往“订单”表加入该订单。

create trigger trigger_订单_inserton 订单after insertas  if (select 状态 from 商品, inserted where 商品.pid = inserted.pid)=1  begin    print 'the goods is being processed'    print 'the order cannot be committed'    rollback transaction --回滚,避免加入  end
create trigger trigger_订单_insert2on 订单after insertas  update 商品 set 数量 = 数量 - inserted.数量  from 商品, inserted  where 商品.pid = inserted.pid
create trigger goodsdelete trigger_商品_deleteon 商品after deleteas  delete from 订单 where 订单.pid in (select pid from deleted)
create trigger trigger_订单_updateon 订单after updateas  if update(订单日期)  begin    raiserror('订单日期不能手动修改',10,1)    rollback transaction  end
create trigger trigger_订单_insert3on 订单after insertas  if (select count(*) from 商品, inserted where 商品.pid = inserted.pid)=0  begin    print '商品不存在'    rollback transaction  end
alter trigger trigger_订单_inserton 订单for insertasinsert into 订单日志 select inserted.Id, inserted.pid,inserted.数量 from inserted 

更多相关文章

  1. SQL Server之JSON 函数详解
  2. MySQL系列多表连接查询92及99语法示例详解教程
  3. Android(安卓)- Manifest 文件 详解
  4. Android的Handler机制详解3_Looper.looper()不会卡死主线程
  5. Selector、shape详解(一)
  6. android2.2资源文件详解4--menu文件夹下的菜单定义
  7. Android发送短信方法实例详解
  8. Android(安卓)读取资源文件实例详解
  9. 详解Android中的屏幕方向

随机推荐

  1. 详细介绍通过JAXB实现XML和对象之间的映
  2. 如何使用bash解析xml的示例代码分析
  3. XML文件使用DOM方法读取的示例代码
  4. 详细介绍JavaBean和XML互转工具类
  5. XML和Schema命名空间的具体实例代码分享
  6. XML文件使用SAX方法读取的示例代码
  7. XML字符转Map工具类的示例代码分享
  8. 详细介绍XML原理代码实例
  9. 解析XML文件的几种方式对比的详细介绍
  10. XML和Schema命名空间的详细介绍