触发器定义

触发器是数据库服务器中发生事件时自动执行的一种特殊存储过程。SQLServer允许为任何特定语句创建多个触发器。它的执行不是由程序调用,也不是手工启动,而是由事件来触发,当对数据库进行操作时就会激活它执行。

触发器分类

分为DML触发器、DDL触发器、登录触发器、嵌套触发器、递归触发器。

DML触发器

定义

如果用户要通过数据操作语言 (DML) 事件编辑数据,则执行 DML 触发器。 DML 事件是针对表或视图的 INSERT、UPDATE 或 DELETE 语句。 在激发任何有效的事件时,将会激发这些触发器,而无论是否会影响任何表行。

分类

AFTER触发器(之后触发)

在执行 INSERT、UPDATE、MERGE 或 DELETE 语句的操作之后执行 AFTER 触发器。 如果违反了约束,则永远不会执行 AFTER 触发器;因此,这些触发器不能用于任何可能防止违反约束的处理。 对于在 MERGE 语句中指定的每个 INSERT、UPDATE 或 DELETE 操作,将为每个 DML 操作触发相应的触发器。

INSTEAD OF触发器

INSTEAD OF触发器替代下列触发语句的标准操作。 因此,触发器可用于对一个或多个列执行错误或值检查,然后在插入、更新或删除行之前执行其他操作。INSTEAD OF触发器的主要优点是可以使不能更新的视图支持更新。 INSTEAD OF触发器的另一个优点是使您得以编写这样的逻辑代码:在允许批处理的其他部分成功的同时拒绝批处理中的某些部分。

下表对 AFTER 触发器和 INSTEAD OF 触发器的功能进行了比较。

函数 AFTER 触发器 INSTEAD OF 触发器
适用范围 表和视图
每个表或视图包含触发器的数量 每个触发操作(UPDATE、DELETE 和 INSERT)包含多个触发器 每个触发操作(UPDATE、DELETE 和 INSERT)包含一个触发器
级联引用 无任何限制条件 不允许在作为级联引用完整性约束目标的表上使用 INSTEAD OF UPDATE 和 DELETE 触发器。
执行 晚于:

约束处理

声明性引用操作

创建插入的 和 删除的 表

触发操作

之前:约束处理

代替:触发操作

之后:创建 插入的 和 删除的 表

执行顺序 可指定第一个和最后一个执行 不适用
插入的和 删除的表中的 varchar(max) 、 nvarchar(max) 和 varbinary(max) 列引用 Allowed Allowed
插入的和 删除的表中的 text 、 ntext 和 image 列引用。 不允许 Allowed

CLR 触发器

CLR 触发器可以是 AFTER 触发器或 INSTEAD OF 触发器。 CLR 触发器还可以是 DDL 触发器。 CLR 触发器将执行在托管代码(在 .NET Framework 中创建并在 Transact-SQL 中上载的程序集的成员)中编写的方法,而不用执行 SQL Server存储过程。

应用场景

DML 触发器可用于强制业务规则和数据完整性、查询其他表并包括复杂的Transact-SQL 语句。 将触发器和触发它的语句作为可在触发器内回滚的单个事务对待。 如果检测到错误(例如,磁盘空间不足),则整个事务即自动回滚。

优点

DML 触发器类似于约束,因为可以强制实体完整性或域完整性。 一般情况下,实体完整性总应在最低级别上通过索引进行强制,这些索引应是 PRIMARY KEY 和 UNIQUE 约束的一部分,或者是独立于约束而创建的。 域完整性应通过 CHECK 约束进行强制,而引用完整性 (RI) 则应通过 FOREIGN KEY 约束进行强制。 当约束支持的功能无法满足应用程序的功能要求时,DML 触发器非常有用。

下面的列表比较 DML 触发器和约束,并在 DML 触发器优于约束时进行标识。

  • DML 触发器可以将更改通过级联方式传播给数据库中的相关表;不过,使用级联引用完整性约束可以更有效地执行这些更改。 除非 REFERENCES 子句定义了级联引用操作,否则 FOREIGN KEY 约束只能用与另一列中的值完全匹配的值来验证列值。

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

    与 CHECK 约束不同,DML 触发器可以引用其他表中的列。 例如,触发器可以使用另一个表中的 SELECT 比较插入或更新的数据,以及执行其他操作,如修改数据或显示用户定义错误信息。

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

  • 一个表中的多个同类 DML 触发器(INSERT、UPDATE 或 DELETE)允许采取多个不同的操作来响应同一个修改语句。

  • 约束只能通过标准化的系统错误消息来传递错误消息。 如果应用程序需要(或能受益于)使用自定义消息和较为复杂的错误处理,则必须使用触发器。

  • DML 触发器可以禁止或回滚违反引用完整性的更改,从而取消所尝试的数据修改。 当更改外键且新值与其主键不匹配时,这样的触发器将生效。 但是,FOREIGN KEY 约束通常用于此目的。

  • 如果触发器表上存在约束,则在 INSTEAD OF 触发器执行后但在 AFTER 触发器执行前检查这些约束。 如果违反了约束,则回滚 INSTEAD OF 触发器操作并且不执行 AFTER 触发器。

DDL触发器

定义

DDL 触发器用于响应各种数据定义语言 (DDL) 事件。 这些事件主要与以关键字 CREATE、ALTER、DROP、GRANT、DENY、REVOKE 或 UPDATE STATISTICS 开头的 Transact-SQL 语句对应。 执行 DDL 式操作的系统存储过程也可以激发 DDL 触发器。

分类

Transact-SQL DDL 触发器

用于执行一个或多个 Transact-SQL 语句以响应服务器范围或数据库范围事件的一种特殊类型的 Transact-SQL 存储过程。 例如,如果执行某个语句(如 ALTER SERVER CONFIGURATION)或者使用 DROP TABLE 删除某个表,则激发 DDL 触发器。

CLR DDL 触发器

CLR 触发器将执行在托管代码(在 .NET Framework 中创建并在 Transact-SQL 中上载的程序集的成员)中编写的方法,而不用执行 SQL Server存储过程。

仅在运行触发 DDL 触发器的 DDL 语句后,DDL 触发器才会激发。 DDL 触发器无法作为 INSTEAD OF 触发器使用。 对于影响局部或全局临时表和存储过程的事件,不会触发 DDL 触发器。

DDL 触发器不会创建特殊的 inserted 和 deleted 表。

可以使用 EVENTDATA 函数捕获有关激发 DDL 触发器的事件以及触发器导致的后续更改的信息。

为每个 DDL 事件创建多个触发器。

与 DML 触发器不同,DDL 触发器的作用域不是架构。 因此,不能将 OBJECT_ID、OBJECT_NAME、OBJECTPROPERTY 和 OBJECTPROPERTYEX 之类的函数用于查询有关 DDL 触发器的元数据。 请改用目录视图。

服务器范围的 DDL 触发器显示在 SQL Server Management Studio 对象资源管理器的“触发器”文件夹中。 此文件夹位于 “服务器对象” 文件夹下。 数据库范围的 DDL 触发器显示在“数据库触发器”文件夹中。 此文件夹位于相应数据库的 “可编程性” 文件夹下。

应用场景

  • 防止对数据库架构进行某些更改。

  • 希望数据库中发生某种情况以响应数据库架构的更改。

  • 记录数据库架构的更改或事件。

优点

更加安全

通过使用 EVENTDATA( ) 函数,可以在触发器中使用XML信息。

登录触发器

定义

登录触发器将为响应 LOGON 事件而激发存储过程。 与 SQL Server实例建立用户会话时将引发此事件。 登录触发器将在登录的身份验证阶段完成之后且用户会话实际建立之前激发。 因此,来自触发器内部且通常将到达用户的所有消息(例如错误消息和来自 PRINT 语句的消息)会传送到 SQL Server 错误日志。 如果身份验证失败,将不激发登录触发器。

应用场景

可以使用登录触发器来审核和控制服务器会话,例如通过跟踪登录活动、限制 SQL Server的登录名或限制特定登录名的会话数。

指定第一个和最后一个触发器

可以对 LOGON 事件定义多个触发器。 通过使用 sp_settriggerorder 系统存储过程,可以将这些触发器中的任何一个指定为针对某事件激发的第一个或最后一个触发器。 SQL Server 不保证其余触发器的执行顺序。

嵌套触发器

如果一个触发器在执行操作时调用了另外一个触发器,而这个触发器又接着调用了下一个触发器,那么就形成了嵌套触发器。嵌套触发器在安装时就被启用,但是可以使用系统存储过程sp_configure禁用和重新启用嵌套触发器。

注意事项

  • 默认情况下,嵌套触发器配置选项是开启的。
  • 在同一个触发器事务中,一个嵌套触发器不能被触发两次。
  • 由于触发器是一个事务,如果在一系列嵌套触发器的任意层次中发生错误,则整个事物都将取消,而且所有数据回滚。

递归触发器

定义

触发器的递归是指一个触发器从其内部再一次激活该触发器。

分类

SqlServer中的递归触发器包括两种:直接递归和间接递归。

  • 直接递归:触发器被触发后并执行一个操作,而该操作又使用一个触发器再次被触发。
  • 间接递归:触发器被触发并执行一个操作,而该操作又使另一个表中的某个触发器被触发,第二个触发器使原始表得到更新,从而再次触发第一个触发器。

默认情况下,递归触发器选项是禁用的。递归触发器最多只能递归16层,如果递归中的第16个触发器激活了第17个触发器,则结果与发布的rollback命令一样,所有数据都将回滚。

触发器优缺点

优点:

  1、触发器是自动的。当对表中的数据做了任何修改之后立即被激活。

  2、触发器可以通过数据库中的相关表进行层叠修改。

  3、触发器可以强制限制。这些限制比用CHECK约束所定义的更复杂。与CHECK约束不同的是,触发器可以引用其他表中的列。

缺点:

  1、增加了系统的复杂性。

  2、嵌套触发器容易出现死锁现象。

  3、触发器并没有提升多少性能。

  4、可移植性差。

  5、占用服务器资源,给服务器造成压力。

  6、复杂的触发器维护困难。

SQLServer之触发器简介的更多相关文章

  1. sqlserver数据库触发器调用外部exe

    sqlserver数据库触发器调用外部exe,同事可以选择参入参数! sqlserver使用 master..xp_cmdshell 进行外部exe的执行. 使用master..xp_cmdshell ...

  2. SqlServer添加触发器死锁的原因

    之前遇到过SqlServer添加触发器死锁的情况,纠结了很长时间 最近发现原来是因为我在建表的时候,把id设成主键后,系统默认了加一个聚集的索引 就是聚集索引把表锁住了

  3. 知方可补不足~sqlserver中触发器的使用

    回到目录 触发器在过去的10年中,即存储过程和ado.net称霸江湖期间是那么的重要,而现在,trigger显得不是那么必要的,我们很少将复杂的业务写在SQL里,当然也会没有机会写到trigger里了 ...

  4. [转帖]SQLSERVER 使用触发器实现 禁用sa用户 在非本机登录

    原贴地址: https://blog.csdn.net/reblue520/article/details/51580102 具体的方法为: 创建一个触发器 CREATE TRIGGER forbid ...

  5. 001.SQLServer高可用简介

    一 SQLServer高可用集群相关概念 1.1 Windows故障转移群集 Windows故障转移群集是由多个服务器组成的共同提供某高可用服务,该服务用于防止单台服务器故障导致服务失效.故障转移群集 ...

  6. 在SQLServer使用触发器实现数据完整性

    1.实现数据完整性的手段 在sqlserver中,在服务器端实现数据完整性主要有两种手段:一种是在创建表时定义数据完整性,主要分为:实体完整性.域完整性.和级联参照完整性:实现的手段是创建主键约束.唯 ...

  7. mssql sqlserver 数据类型sql_variant简介说明

    转自: http://www.maomao365.com/?p=9712  摘要: 下文讲述sqlserver中sql_variant数据类型定义.赋值.应用的相关说明,如下所示: 实验环境:sql ...

  8. sqlserver数据库触发器和存储过程案例学习

      --创建表 create table zhuangzhan ( name ), code ) ); --往表添加一列 alter table zhuangzhan add descition in ...

  9. Sqlserver的触发器的简单使用

    1,触发器有两种 (1)After触发器(之后触发) 触发器有个好处:就是你之前有过什么操作他会将你的操作的数据信息完整的保存下来,比如你删过什么信息,如果用触发器,那么删除后就会显示两行受影响,那么 ...

随机推荐

  1. Linux中断程序命令

    在运行 python 脚本的时候想要中断程序,发现如下情况: ctrl+c 居然无法中断程序! 这时候尝试 ctrl+d 还是毫无效果,最后尝试 ctrl+\: 查看该程序是否还在运行 ps aux ...

  2. Linux下python2和python3共存

    python下载地址: https://www.python.org/ftp/python/3.4.4/Python-3.4.4.tar.xz 下载命令: wget https://www.pytho ...

  3. 一张脑图说清 Nginx 的主流程

    一张脑图说清 Nginx 的主流程 这个脑图在 nginx-1.14.0-research 上.这是我在研究nginx的http模块的时候画的.基本上把 Nginx 主流程(特别是 HTTP 的部分) ...

  4. Qt之自定义检索框

    1.效果展示 今天这篇文章主要讲解的是自定义搜索框,不仅仅支持搜索,而且可以支持搜索预览,具体请看效果图1.网上也有一些比较简单明了的自定义搜索框,比如Qt之自定义搜索框,讲的也比较详细,不过本文的侧 ...

  5. java基础(十四)-----详解匿名内部类——Java高级开发必须懂的

    在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意的事项.匿名内部类使用的形参为何要为final. 使用匿名内部类内部类 匿名内部类由于没有名字,所以它的创建方式有点儿奇怪.创建格式如下: n ...

  6. .NET Core中的路由约束

    背景介绍 上周给大家分享了Nancy in .NET Core学习笔记 - 路由之后, 就一直在考虑.NET Core能否实现和Nancy中一样的路由约束, 最近查阅了一下MSDN及一些国外博客, 发 ...

  7. 图像识别基本算法之SURF

    图像识别.人脸识别可行的算法有很多.但是作为学习,如果能理清这个问题研究的历程及其主线,会对你深入理解当前研究最新的发展有很多帮助.本文是自己在学习过程中的笔记,大多内容来自于网络,出处请参考最后的引 ...

  8. 从锅炉工到AI专家(11)(END)

    语音识别 TensorFlow 1.x中提供了一个语音识别的例子speech_commands,用于识别常用的命令词汇,实现对设备的语音控制.speech_commands是一个很成熟的语音识别原型, ...

  9. 知其所以然~分布式事务cap

    背景 一致性是一个抽象的.具有多重含义的计算机术语,在不同应用场景下,有不同的定义和含义.在传统的IT时代,一致性通常指强一致性,强一致性通常体现在你中有我.我中有你.浑然一体:而在互联网时代,一致性 ...

  10. JavaScriptCore全面解析

    本文由云+社区发表 作者:殷源,专注移动客户端开发,微软Imagine Cup中国区特等奖获得者 JavaScript越来越多地出现在我们客户端开发的视野中,从ReactNative到JSpatch, ...