sp_settriggerorder (Transact-SQL)

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

指定 AFTER 首先或最后触发的触发器。 在第 AFTER 一个触发器和最后一个触发器之间触发的触发器按未定义的顺序执行。

Transact-SQL 语法约定

语法

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),可以是 DELETEUPDATELOGONINSERTDDL 事件中列出的任何 T-SQL 语句事件。 无法指定事件组。

只有在该触发器定义为该语句类型的触发器之后,才能将触发器指定为FirstLast语句类型的触发器。 例如,如果将INSERTTR1触发器TR1定义为触发器,则可以为INSERTT1指定First触发器。 如果TR1仅定义为INSERT触发器,则数据库引擎返回错误,该错误设置为First语句的或Last触发器UPDATE。 有关详细信息,请参阅备注部分。

@namespace= { 'DATABA标准版' |“标准版RVER” |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 副本 (replica)tion 触发器上使用,或者用于sp_settriggerorder将副本 (replica)触发器Last更改为或None触发器,则订阅无法正常工作。

DDL 触发器

如果具有数据库范围的 DDL 触发器和服务器范围的 DDL 触发器存在于同一事件上,则可以指定这两个FirstLast触发器都是触发器或触发器。 但是,服务器作用域的触发器始终最先触发。 一般情况下,同一事件中 DDL 触发器的执行顺序如下:

  1. 标记的服务器级触发器 First
  2. 其他服务器级触发器
  3. 标记的服务器级触发器 Last
  4. 标记的数据库级触发器 First
  5. 其他数据库级触发器
  6. 标记的数据库级触发器 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';