浅谈SQL Server 数据库之触发器_Eagle's World_百度空间

//from

触发器的特征:

  1、触发器是在对表进行增、删、改时,自动执行的存储过程。触发器常用于强制业务规则,它是一种高级约束,通过事件进行触发而被执行。

  2、触发器是一个特殊的事务单元,可以引用其他表中的列执行特殊的业务规则或数据逻辑关系。当出现错误时,可以执行rollback transaction操作将整个触发器以及触发它的T-SQL语句一并回滚(不需显示声明begin transaction)。

  3、每个触发器将用到的两个临时表:

  deleted 临时表:用于临时存放被删除的记录行副本(包括delete和update语句所影响的数据行);

  注意:被删除的记录行,首先从原始表中删除,并保存到触发器表。然后从触发器表中删除,再保存到deleted表。

  inserted临时表:用于临时存放插入的记录行副本(包括insert和update语句所影响的数据行);

  deleted表和inserted表的特征:

  > 这两个表的表结构与该触发器作用的表相同;

  > 这两个表是逻辑表,并且由系统管理;

  > 这两个表是动态驻留在内存中的(不是存储在数据库中),当触发器工作完成后,它们也被删除;

  > 这两个表是只读的,即只能运用select语句查看(用户不能直接更改);

  4、所创建的触发器(insert、delete、update)是在原表数据行已经修改完成后再触发。所以,触发器是在约束检查之后才执行。

  什么时候使用触发器?

  a、实现主外键关系所不能保证的复杂参照完整性和数据的一致性。

  不过,通过“级联引用完整性约束”可以更有效地执行这些更改。

  b、防止恶意或错误的 INSERT、UPDATE 以及 DELETE 操作,并强制执行比 CHECK 约束定义的限制更为复杂的其他限制。

  > 与 CHECK 约束不同(check约束只能引用自身表中的列),DML触发器可以引用其他表中的列;

  > 触发器可以完成所有约束的功能,但不一定是{zj0}方案;

  > 触发器能够使用自定义信息和较为复杂的错误处理;

  c、DML 触发器可以评估数据修改前后表的状态,并根据该差异采取措施。

  d、一个表中的同一个修改语句的DML触发器,允许被多个不同的操作(INSERT、UPDATE 或 DELETE)来响应;

  触发器的类型:

  insert 触发器;(略)

  delete 触发器;(略)

  update 触发器:在修改表中记录行或某列数据时触发执行;

  注意:update(列)函数:实现检测某列是否被修改。

  update 更新操作分为两步:

  首先,“删除”更改前原有数据行:删除的原有数据行将复制到deleted临时表中;

  然后,“插入”更改后的新数据行:插入新数据行到原始表,同时将新数据行保存到inserted临时表和触发器表中;

  创建触发器的注意点:

  1、create trigger必须是批处理(go)的{dy}条语句;

  2、一个触发器语句只能用到一个表或一个视图中;

  on 表名/ 视图名

  3、一个触发器语句可以执行多个操作;

  for delete,insert,update -- 无先后顺序的任意组合

  4、建议DML触发器不返回任何结果。这是因为对这些返回结果的特殊处理必须写入每个允许对触发器表进行修改的应用程序中。

  若要防止从 DML 触发器返回任何结果,请不要在触发器定义中包含select语句或变量赋值;

  如果必须在触发器中进行变量赋值,则应该在触发器被触发之前使用set nocount on语句以避免返回任何结果集;

  注意:未来版本的SQL Server 中,将会删除从触发器返回结果集的功能。

  5、如果“触发器表”本身也存在约束,则在执行insert、delete、update触发器前,首先会检查“触发器表”上存在的约束。如果不满足约束,则不会执行其insert、delete、update触发器。

  查看当前数据库中的所有触发器

  select * from sys.triggers

  创建临时表 #tableName

  create table #tableName

=====================

例:以下触发器实现:向Device表中插入记录时,检验Bridge表中是否含有要插入的这些记录的BridgeCode。——检验参照完整性。(即:Bridge表的BridgeCode为Device表中的Bridgecode的外键)

CREATE TRIGGER [dbo].[Device_BridgeCode

   ON [dbo].[Device

   Instead of Insert

AS
BEGIN

SET NOCOUNT ON;

    -- Insert statements for trigger here
    If Exists(Select inserted.* From Bridge,inserted Where Bridge.BridgeCode=inserted.BridgeCode )
      Begin
        Insert into Device Select * From inserted;
      End

END

======================

例2:以下触发器实现 对于一个表,插入相同名称(如项目表中同一个项目的多次更新)的数据时只保存{zx1}的一条,以前的统统删掉。

create trigger ins_trigger on 学生表 instead of insert
as
begin
    declare @max int
    declare @count int
    select @count=count(学生表.id), @max=max(学生表.id)
    from 学生表, inserted
    where 学生表.id = inserted.id
    if @count = 0 insert 学生表 select * from inserted
end
go



郑重声明:资讯 【浅谈SQL Server 数据库之触发器_Eagle's World_百度空间】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——