DDL 触发器

DDL 触发器会在多种数据定义语言(DDL)事件发生时触发反应。 这些事件主要对应于以关键字 CREATE、ALTER、DROP、GRANT、DENY、REVOKE 或 UPDATE STATISTICS 开头的 Transact-SQL 语句。 某些系统存储过程在执行类似于 DDL 的操作时,也可以触发 DDL 触发器。

若要执行以下操作,请使用 DDL 触发器:

  • 防止对数据库架构进行某些更改。

  • 为了响应数据库架构的更改,在数据库中触发某些事件。

  • 记录数据库架构中的更改或事件。

重要

测试 DDL 触发器以确定其对运行的系统存储过程的响应。 例如,CREATE TYPE 语句和 sp_addtype 存储过程都将触发在CREATE_TYPE事件上创建的 DDL 触发器。

DDL 触发器的类型

Transact-SQL DDL 触发器
一种特殊类型的 Transact-SQL 存储过程,用于执行一个或多个 Transact-SQL 语句,以响应服务器范围或数据库范围的事件。 例如,如果执行 ALTER SERVER CONFIGURATION 等语句或使用 DROP TABLE 删除表,则 DDL 触发器可能会触发。

CLR DDL 触发器
相较于执行Transact-SQL存储过程,CLR触发器执行以托管代码编写的一个或多个方法,这些方法是由.NET Framework中创建并上传到SQL Server的程序集的成员。

只有在运行触发它们的 DDL 语句后,DDL 触发器才会触发。 DDL 触发器不能用作 INSTEAD OF 触发器。 DDL 触发器不会触发以响应影响本地或全局临时表和存储过程的事件。

DDL 触发器不创建特殊 inserteddeleted 表。

使用 EVENTDATA 函数捕获有关触发 DDL 触发器的事件的信息以及触发器引起的后续更改。

要为每个 DDL 事件创建多个触发器。

与 DML 触发器不同,DDL 触发器的范围不限定为架构。 因此,不能使用OBJECT_ID、OBJECT_NAME、OBJECTPROPERTY 和 OBJECTPROPERTYEX 等函数来查询有关 DDL 触发器的元数据。 请改用目录视图。

服务器范围的 DDL 触发器显示在 触发器 文件夹中的 SQL Server Management Studio 对象资源管理器中。 此文件夹位于 “服务器对象” 文件夹下。 数据库范围的 DDL 触发器显示在 “数据库触发器” 文件夹中。 此文件夹位于相应数据库的 可编程性 文件夹下。

重要

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

DDL 触发器范围

DDL 触发器可以在响应当前数据库或当前服务器上处理的 Transact-SQL 事件时触发。 触发器的范围取决于事件。 例如,在响应CREATE_TABLE事件时创建的 DDL 触发器可以在数据库或服务器实例中发生CREATE_TABLE事件时触发。 为响应CREATE_LOGIN事件而创建的 DDL 触发器只能在服务器实例中发生CREATE_LOGIN事件时执行此作。

在以下示例中,每当数据库中发生DROP_TABLEALTER_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 触发器,其行为就像在用户设计的数据库中创建的触发器一样。 可以通过查询 sys.triggers 目录视图来获取有关 DDL 触发器的信息。 可以在创建触发器的数据库上下文中查询 sys.triggers ,也可以通过将数据库名称指定为标识符(例如 master.sys.triggers)。

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

指定 Transact-SQL 语句或语句组

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

DDL 触发器可在运行一个或多个特定 Transact-SQL 语句后触发。 在上一示例中,触发器 safety 会在任何 DROP_TABLEALTER_TABLE 事件后触发。 有关可指定触发 DDL 触发器的 Transact-SQL 语句的列表,以及触发器可以触发的范围,请参阅 DDL 事件

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

DDL 触发器可以在执行任何属于类似事件预定义分组的 Transact-SQL 事件后触发。 例如,如果希望在运行任何 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 事件组

任务 主题
介绍如何创建、修改、删除或禁用 DDL 触发器。 实现 DDL 触发器
介绍如何创建 CLR DDL 触发器。 创建 CLR 触发器
介绍如何返回有关 DDL 触发器的信息。 获取有关 DDL 触发器的信息
介绍如何使用 EVENTDATA 函数返回有关触发 DDL 触发器的事件的信息。 使用 EVENTDATA 函数
介绍如何管理触发器安全性。 管理触发器安全性

另请参阅

DML 触发器
登录触发器
CREATE TRIGGER (Transact-SQL)