设计 DDL 触发器

在设计 DDL 触发器之前,必须:

  • 必须了解 DDL 触发器的作用域。

  • 必须确定激发触发器的 Transact-SQL 语句或语句组。

安全说明安全说明

触发器内部的恶意代码可以在升级后的权限下运行。有关如何帮助减少此威胁的详细信息,请参阅管理触发器安全性

注意注意

对于影响局部或全局临时表和存储过程的事件,不会触发 DDL 触发器。

了解触发器的作用域

在响应当前数据库或服务器上处理的 Transact-SQL 事件时,可以触发 DDL 触发器。触发器的作用域取决于事件。例如,每当数据库中或服务器实例上发生 CREATE_TABLE 事件时,都会激发为响应 CREATE_TABLE 事件创建的 DDL 触发器。仅当服务器上发生 CREATE_LOGIN 事件时,才能激发为响应 CREATE_LOGIN 事件创建的 DDL 触发器。

在下面的示例中,每当数据库中发生 DROP TABLE 或 ALTER TABLE 事件时,都会激发 DDL 触发器 safety。

CREATE TRIGGER safety 
ON DATABASE 
FOR DROP_TABLE, ALTER_TABLE 
AS 
   PRINT 'You must disable Trigger "safety" to drop or alter tables!' 
   ROLLBACK
;

在下面的示例中,如果当前服务器实例上发生任何 CREATE_DATABASE 事件,DDL 触发器将输出消息。此示例使用 EVENTDATA 函数检索相应的 Transact-SQL 语句的文本。有关如何将 EVENTDATA 与 DDL 触发器配合使用的详细信息,请参阅使用 EVENTDATA 函数

IF EXISTS (SELECT * FROM sys.server_triggers
    WHERE name = 'ddl_trig_database')
DROP TRIGGER ddl_trig_database
ON ALL SERVER;
GO
CREATE TRIGGER ddl_trig_database 
ON ALL SERVER 
FOR CREATE_DATABASE 
AS 
    PRINT 'Database Created.'
    SELECT EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')
GO
DROP TRIGGER ddl_trig_database
ON ALL SERVER;
GO

本主题后面的“选择触发 DDL 触发器的特定 DDL 语句”一部分中提供了一些链接,通过这些链接可以找到将 Transact-SQL 语句映射到为它们指定的作用域的列表。

数据库范围内的 DDL 触发器都作为对象存储在创建它们的数据库中。可以在 master 数据库中创建 DDL 触发器,这些触发器的行为与在用户设计的数据库中创建的 DDL 触发器的行为类似。可以通过查询 sys.triggers 目录视图获取有关 DDL 触发器的信息。可以在创建触发器的数据库上下文中或通过指定数据库名称作为标识符(例如 master.sys.triggers),查询 sys.triggers

服务器范围内的 DDL 触发器作为对象存储在 master 数据库中。然而,可以通过在任何数据库上下文中查询 sys.server_triggers 目录视图,获取有关服务器范围内的 DDL 触发器的信息。

有关如何检索 DDL 触发器的元数据的详细信息,请参阅获取有关 DDL 触发器的信息

指定 Transact-SQL 语句或语句组

可以创建一些 DDL 触发器,在响应一个或多个特殊 DDL 语句或预定义 DDL 语句组时激发。

选择触发 DDL 触发器的特定 DDL 语句

可以安排在运行一个或多个特定 Transact-SQL 语句后触发 DDL 触发器。在前面的示例中,在发生任何 DROP_TABLE 或 ALTER_TABLE 事件后触发 safety 触发器。有关可指定激发 DDL 触发器的 Transact-SQL 语句列表,请参阅 DDL 事件

选择触发 DDL 触发器的一组预定义的 DDL 语句

可以在执行属于一组预定义的相似事件的任何 Transact-SQL 事件后激发 DDL 触发器。例如,如果希望在运行 CREATE TABLE、ALTER TABLE 或 DROP TABLE 语句后触发 DDL 触发器,则可以在 CREATE TRIGGER 语句中指定 FOR DDL_TABLE_EVENTS。运行 CREATE TRIGGER 后,事件组涵盖的事件都添加到 sys.trigger_events 目录视图中。

注意注意

在 SQL Server 2005 中,如果对事件组创建触发器,则 sys.trigger_events 不包括有关该事件组的信息,而 sys.trigger_events 仅包括有关该组涵盖的个别事件的信息。在 SQL Server 2008 中,sys.trigger_events 保留有关创建触发器的事件组的元数据,以及有关该事件组涵盖的个别事件的元数据。因此,对 SQL Server 2008 中事件组所涵盖的事件的更改并不适用于在 SQL Server 2005 中对这些事件组创建的 DDL 触发器。

有关可用于 DDL 触发器的预定义 DDL 语句组、事件组所涵盖的特定语句以及可以对这些事件组进行编程的作用域的列表,请参阅 DDL 事件组