sp_settriggerorder (Transact-SQL)
适用于: SQL Server Azure SQL 数据库 Azure SQL 托管实例
指定 AFTER
首先或最后触发的触发器。 在第 AFTER
一个触发器和最后一个触发器之间触发的触发器按未定义的顺序执行。
语法
sp_settriggerorder
[ @triggername = ] N'triggername'
, [ @order = ] 'order'
, [ @stmttype = ] 'stmttype'
[ , [ @namespace = ] 'DATABASE' | 'SERVER' | NULL ]
[ ; ]
参数
[ @triggername = ] N'triggername'
触发器的名称及其所属架构(如果适用),其顺序是要设置或更改的。 @triggername为 nvarchar(517),无默认值,格式为 [trigger_schema . ] trigger_name。 如果名称与触发器不对应,或者该名称与 INSTEAD OF
触发器相对应,该过程将返回错误。 不能为 DDL 或登录触发器指定架构。
[ @order = ] 'order'
触发器的新顺序的设置。 @order为 varchar(10),可以是以下任一值。
值 | 说明 |
---|---|
First |
触发器被第一个触发。 |
Last |
触发器被最后一个触发。 |
None |
触发器以未定义的顺序触发。 |
重要
First
触发器Last
必须是两个不同的触发器。
[ @stmttype = ] 'stmttype'
指定触发触发器的 Transact-SQL 语句。 @stmttype是 varchar(50),可以是 DELETE
UPDATE
LOGON
INSERT
DDL 事件中列出的任何 T-SQL 语句事件。 无法指定事件组。
只有在该触发器定义为该语句类型的触发器之后,才能将触发器指定为First
Last
语句类型的触发器。 例如,如果将INSERT
TR1
触发器TR1
定义为触发器,则可以为INSERT
表T1
指定First
触发器。 如果TR1
仅定义为INSERT
触发器,则数据库引擎返回错误,该错误设置为First
语句的或Last
触发器UPDATE
。 有关详细信息,请参阅备注部分。
@namespace = { 'DATABASE' |“SERVER” |NULL }
当@triggername是 DDL 触发器时,@namespace指定是使用数据库范围还是服务器范围创建@triggername。 如果 @triggername 是登录触发器, SERVER
则必须指定。 有关 DDL 触发器范围的详细信息,请参阅 DDL 触发器。 如果未指定或 NULL
指定, 则@triggername 为 DML 触发器。
返回代码值
0
(成功)和 1
(失败)。
注解
本部分讨论有关数据操作语言(DML)和数据定义语言(DDL)触发器的注意事项。
DML 触发器
单个表上每个语句只能有一 First
个和一个 Last
触发器。
First
如果已在表、数据库或服务器上定义触发器,则不能将新触发器指定为First
同一个表、数据库或服务器的同一@stmttype。 此限制还应用 Last
触发器。
复制将为包含在立即更新订阅或排队更新订阅中的任意表自动生成第一个触发器。 复制要求其触发器是第一个触发器。 在尝试将带有第一个触发器的表包含在立即更新订阅或排队更新订阅中时,复制将引发错误。 如果在订阅中包含表后尝试将触发器设为第一个触发器, sp_settriggerorder
则返回错误。 如果在 ALTER TRIGGER
复制触发器上使用,或者用于 sp_settriggerorder
将复制触发器 Last
更改为某个或 None
触发器,则订阅无法正常工作。
DDL 触发器
如果具有数据库范围的 DDL 触发器和服务器范围的 DDL 触发器存在于同一事件上,则可以指定这两个First
Last
触发器都是触发器或触发器。 但是,服务器作用域的触发器始终最先触发。 一般情况下,同一事件中 DDL 触发器的执行顺序如下:
- 标记的服务器级触发器
First
- 其他服务器级触发器
- 标记的服务器级触发器
Last
- 标记的数据库级触发器
First
- 其他数据库级触发器
- 标记的数据库级触发器
Last
常规触发器注意事项
ALTER TRIGGER
如果语句更改了第一个或最后一个触发器,First
则最初在触发器上设置的或Last
属性将被删除,并且值将被None
替换。 必须使用 重置 sp_settriggerorder
订单值。
如果必须将同一触发器指定为多个语句类型的第一个或最后一个顺序, sp_settriggerorder
则必须为每个语句类型执行。 此外,必须先为语句类型定义触发器,然后才能将其指定为 First
该语句类型触发的触发器 Last
。
权限
使用服务器范围(已创建 ON ALL SERVER
)或登录触发器设置 DDL 触发器的顺序需要 CONTROL SERVER
权限。
使用数据库范围(已创建 ON DATABASE
)设置 DDL 触发器的顺序需要 ALTER ANY DATABASE DDL TRIGGER
权限。
设置 DML 触发器的顺序需要 ALTER
对定义触发器的表或视图具有权限。
示例
A. 设置 DML 触发器的触发顺序
以下示例指定触发器uSalesOrderHeader
是在表上Sales.SalesOrderHeader
发生操作后触发的第一个UPDATE
触发器。
USE AdventureWorks2022;
GO
EXEC sp_settriggerorder @triggername = 'Sales.uSalesOrderHeader',
@order = 'First',
@stmttype = 'UPDATE';
B. 设置 DDL 触发器的触发顺序
以下示例指定触发器ddlDatabaseTriggerLog
是在数据库中发生AdventureWorks2022
事件后触发的第一个ALTER_TABLE
触发器。
USE AdventureWorks2022;
GO
EXEC sp_settriggerorder @triggername = 'ddlDatabaseTriggerLog',
@order = 'First',
@stmttype = 'ALTER_TABLE',
@namespace = 'DATABASE';