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) 在插入和删除表中的列引用 |
允许 | 允许 |
text 、ntext 和image 在插入和删除表中的列引用 |
不允许 | 允许 |
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)