DML 触发器

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例

DML 触发器是一种特殊的存储过程类型,当发生影响触发器中定义的表或视图的数据作语言(DML)事件时,该存储过程会自动生效。 DML 事件包括 INSERTUPDATEDELETE 语句。 DML 触发器可用于强制业务规则和数据完整性、查询其他表并包括复杂的 Transact-SQL 语句。 将触发器和触发它的语句作为单个事务进行处理,其中可以在触发器内回滚单个事务。 如果检测到严重错误(例如,磁盘空间不足),则整个事务将自动回滚。

优点

DML 触发器类似于约束,具体体现在可以强制实施实体完整性或域完整性。 通常,实体完整性应始终由属于PRIMARY KEYUNIQUE约束的索引在最低级别强制实施,或者索引独立于约束进行创建。 域完整性应通过 CHECK 约束强制执行,并且应通过 FOREIGN KEY 约束强制实施引用完整性(RI)。 当约束支持的功能无法满足应用程序的功能需求时,DML 触发器最有用。

下面的列表比较了 DML 触发器和约束,并识别了 DML 触发器相比约束具有优势的情况。

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

  • 它们可以防范恶意或错误的 INSERT 操作、UPDATE 操作,以及 DELETE 操作,并强制实施比使用 CHECK 约束定义的限制更复杂的其他限制。

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

  • 它们可以评估表在数据修改前后的状态,并根据该差异采取措施。

  • 表中多个相同类型的 DML 触发器(INSERTUPDATEDELETE)允许在同一修改语句下执行多种不同的操作。

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

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

  • 如果在触发器表上存在约束,它们会在INSTEAD OF触发器执行后被检查,但在AFTER触发器执行前被检查。 如果违反了约束,则 INSTEAD OF 的触发动作会被回滚,并且 AFTER 触发器不会被执行。

DML 触发器的类型

AFTER 触发器

AFTER触发器在INSERTUPDATEMERGEDELETE语句的操作完成后执行。 AFTER 如果发生约束冲突,则永远不会执行触发器。 因此,这些触发器不能用于任何可能会防止约束违规的处理。 对于在 MERGE 语句中指定的每个 INSERTUPDATEDELETE 操作,都会为每个 DML 操作触发相应的触发器。

INSTEAD OF 触发器

INSTEAD OF 触发器将替代触发语句的标准操作。 因此,它们可用于对一个或多个列执行错误或值检查,并在插入、更新或删除行之前执行其他操作。 例如,当要在工资表中的时薪列中更新的值超过指定值时,可以定义触发器,以生成错误消息并回滚事务,或在将记录插入工资表之前将新记录插入审核记录。 INSTEAD OF 触发器的主要优势在于启用无法更新的视图,以便支持更新。 例如,基于多个基表的 INSTEAD OF 视图必须使用触发器来支持在多个表中引用数据的插入、更新和删除。 触发器的另 INSTEAD OF 一个优点是,它们使你能够编写可拒绝批处理部分的代码逻辑,同时让批处理的其他部分成功。

下表比较了AFTER触发器与INSTEAD OF触发器的功能。

函数 AFTER 触发器 INSTEAD OF 触发器
适用性 表和视图
每个表或视图的数量 每个触发操作多个(UPDATEDELETEINSERT 每个触发操作一个(UPDATEDELETEINSERT)。
级联引用 不存在任何限制 不允许在作为级联引用完整性约束目标的表上使用 INSTEAD OF UPDATEDELETE 触发器。
Execution 之后:

约束处理

声明性引用操作

创建inserteddeleted

触发操作
之前:约束处理

代替:触发操作

在创建 inserteddeleted 表之后
执行顺序 可以设置第一个和最后一个执行过程 不适用
varchar(max)nvarchar(max)varbinary(max) 列引用于 inserteddeleted 表中 允许 允许
inserteddeleted 表中的 textntextimage 列引用 不允许 允许

CLR 触发器

公共语言运行时 (CLR) 触发器可以是 AFTERINSTEAD OF 触发器。 CLR 触发器也可以是数据定义语言 (DDL) 触发器。 CLR 触发器将执行在托管代码(在 .NET Framework 中创建并在 SQL Server 中上载的程序集的成员)中编写的一个或多个方法,而不用执行 Transact-SQL 存储过程。

任务 文章
介绍如何创建 DML 触发器。 创建 DML 触发器
介绍如何创建 CLR 触发器。 创建 CLR 触发器
介绍如何创建 DML 触发器,以处理单行和多行数据修改。 创建 DML 触发器以处理多行数据
介绍如何嵌套触发器。 创建嵌套触发器
介绍如何指定AFTER触发器的触发顺序。 指定第一个和最后一个触发器
介绍如何在触发器代码中使用特殊的插入和删除的表。 使用插入的和删除的表
介绍如何修改或重命名 DML 触发器。 修改或重命名 DML 触发器
介绍如何查看有关 DML 触发器的信息。 获取有关 DML 触发器的信息
介绍如何删除或禁用 DML 触发器。 删除或禁用 DML 触发器
介绍如何管理触发器安全性。 管理触发器安全性