DML 触发器

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

DML 触发器权益

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

以下列表将 DML 触发器与约束进行比较,并确定 DML 触发器何时具有优势。

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

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

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

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

  • 表上具有相同类型的多个 DML 触发器(INSERT、UPDATE 或 DELETE)允许对同一修改语句执行多个不同的作。

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

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

  • 如果触发器表上存在约束,则会在 INSTEAD OF 触发器执行之后、AFTER 触发器执行之前对它们进行检查。 如果违反了约束,则会回滚 INSTEAD OF 触发器的操作,并且未执行 AFTER 触发器的操作。

DML 触发器的类型

AFTER 触发器
在完成 INSERT、UPDATE、MERGE 或 DELETE 语句后,将执行 AFTER 触发器。 发生约束冲突时,不执行 AFTER 触发器,所以这些触发器不能用于任何可能避免约束冲突的处理。 对于 MERGE 语句中指定的每个 INSERT、UPDATE 或 DELETE 操作,都会为每个 DML 操作触发相应的触发器。

替代触发器
INSTEAD OF 触发器覆盖触发语句的标准操作。 因此,它们可用于对一个或多个列进行错误或值检查,并在插入、更新或删除行或多行之前执行其他操作。 例如,当工资表中每小时工资列的更新值超过指定值时,可以定义一个触发器,要么生成错误消息并回滚事务,要么在将记录插入工资表之前将新记录插入审计追踪。 INSTEAD OF 触发器的主要优点是,它们使通常不可更新的视图能够支持更新。 例如,基于多个基表的视图必须使用 INSTEAD OF 触发器来支持在多个表中引用数据的插入、更新和删除。 INSTEAD OF 触发器的另一个优点是,它们使你能够编写逻辑,该逻辑可以拒绝批次的某些部分,同时允许批次的其他部分成功执行。

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

功能 后置触发器 代替触发器
适用范围 表格 表和视图
每个表或视图的数量 每个触发作的多个 (UPDATE、DELETE 和 INSERT) 每个触发操作一个(UPDATE、DELETE 和 INSERT)
级联引用 不适用任何限制 不允许在作为级联引用完整性约束目标的表上使用 INSTEAD OF UPDATE 和 DELETE 触发器。
执行 之后:

约束处理
声明性引用作
插入删除 的表创建
触发动作
之前:约束处理

代替:触发动作

之后: 插入表创建删除表创建
执行顺序 可以指定第一次和最后一次执行 不適用
varchar(max)nvarchar(max)varbinary(max)插入删除表中的列引用 允许 允许
textntextimage插入删除表中的列引用 不允许 允许

CLR 触发器
CLR 触发器可以是 AFTER 触发器或 INSTEAD OF 触发器。 CLR 触发器也可以是 DDL 触发器。 与执行 Transact-SQL 存储过程不同,CLR 触发器执行以托管代码编写的一个或多个方法,这些方法是 .NET Framework 中创建并在 SQL Server 中上传的程序集的成员。

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

另请参阅

CREATE TRIGGER (Transact-SQL)
ALTER TRIGGER (Transact-SQL)
DROP TRIGGER (Transact-SQL)
DISABLE TRIGGER (Transact-SQL)
触发器函数(Transact-SQL)