适用于:SQL Server
Azure SQL 数据库
Azure SQL 托管实例
DML 触发器是一种特殊的存储过程类型,当发生影响触发器中定义的表或视图的数据作语言(DML)事件时,该存储过程会自动生效。 DML 事件包括 INSERT、 UPDATE或 DELETE 语句。 DML 触发器可用于强制业务规则和数据完整性、查询其他表并包括复杂的 Transact-SQL 语句。 将触发器和触发它的语句作为单个事务进行处理,其中可以在触发器内回滚单个事务。 如果检测到严重错误(例如,磁盘空间不足),则整个事务将自动回滚。
优点
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 触发器
AFTER触发器在INSERT、UPDATE、MERGE或DELETE语句的操作完成后执行。 AFTER 如果发生约束冲突,则永远不会执行触发器。 因此,这些触发器不能用于任何可能会防止约束违规的处理。 对于在 MERGE 语句中指定的每个 INSERT、UPDATE 或 DELETE 操作,都会为每个 DML 操作触发相应的触发器。
INSTEAD OF 触发器
INSTEAD OF 触发器将替代触发语句的标准操作。 因此,它们可用于对一个或多个列执行错误或值检查,并在插入、更新或删除行之前执行其他操作。 例如,当要在工资表中的时薪列中更新的值超过指定值时,可以定义触发器,以生成错误消息并回滚事务,或在将记录插入工资表之前将新记录插入审核记录。 INSTEAD OF 触发器的主要优势在于启用无法更新的视图,以便支持更新。 例如,基于多个基表的 INSTEAD OF 视图必须使用触发器来支持在多个表中引用数据的插入、更新和删除。 触发器的另 INSTEAD OF 一个优点是,它们使你能够编写可拒绝批处理部分的代码逻辑,同时让批处理的其他部分成功。
下表比较了AFTER触发器与INSTEAD OF触发器的功能。
| 函数 | AFTER 触发器 |
INSTEAD OF 触发器 |
|---|---|---|
| 适用性 | 表 | 表和视图 |
| 每个表或视图的数量 | 每个触发操作多个(UPDATE、DELETE 和 INSERT) |
每个触发操作一个(UPDATE、DELETE 和 INSERT)。 |
| 级联引用 | 不存在任何限制 | 不允许在作为级联引用完整性约束目标的表上使用 INSTEAD OF UPDATE 和 DELETE 触发器。 |
| Execution | 之后: 约束处理 声明性引用操作 创建 inserted和deleted表触发操作 |
之前:约束处理 代替:触发操作 在创建 inserted 和 deleted 表之后 |
| 执行顺序 | 可以设置第一个和最后一个执行过程 | 不适用 |
varchar(max)、nvarchar(max) 和 varbinary(max) 列引用于 inserted 和 deleted 表中 |
允许 | 允许 |
inserted 和 deleted 表中的 text、ntext 和 image 列引用 |
不允许 | 允许 |
CLR 触发器
公共语言运行时 (CLR) 触发器可以是 AFTER 或 INSTEAD OF 触发器。 CLR 触发器也可以是数据定义语言 (DDL) 触发器。 CLR 触发器将执行在托管代码(在 .NET Framework 中创建并在 SQL Server 中上载的程序集的成员)中编写的一个或多个方法,而不用执行 Transact-SQL 存储过程。
相关任务
| 任务 | 文章 |
|---|---|
| 介绍如何创建 DML 触发器。 | 创建 DML 触发器 |
| 介绍如何创建 CLR 触发器。 | 创建 CLR 触发器 |
| 介绍如何创建 DML 触发器,以处理单行和多行数据修改。 | 创建 DML 触发器以处理多行数据 |
| 介绍如何嵌套触发器。 | 创建嵌套触发器 |
介绍如何指定AFTER触发器的触发顺序。 |
指定第一个和最后一个触发器 |
| 介绍如何在触发器代码中使用特殊的插入和删除的表。 | 使用插入的和删除的表 |
| 介绍如何修改或重命名 DML 触发器。 | 修改或重命名 DML 触发器 |
| 介绍如何查看有关 DML 触发器的信息。 | 获取有关 DML 触发器的信息 |
| 介绍如何删除或禁用 DML 触发器。 | 删除或禁用 DML 触发器 |
| 介绍如何管理触发器安全性。 | 管理触发器安全性 |