适用于:SQL Server
Azure SQL 数据库
Azure SQL 托管实例
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 触发器
用于执行一个或多个 Transact-SQL 语句以响应服务器范围或数据库范围事件的一种特殊类型的 Transact-SQL 存储过程。 例如,如果执行 ALTER SERVER CONFIGURATION 语句,或使用 DROP TABLE 删除表,则 DDL 触发器可能会被触发。
CLR 触发器
公共语言运行时 (CLR) 触发器不是执行 Transact-SQL 存储过程,而是执行用托管代码编写的一个或多个方法,这些方法是 .NET Framework 中创建的程序集的成员,并在 SQL Server 中上传。
仅在运行触发 DDL 触发器的 DDL 语句后,DDL 触发器才会触发。 DDL 触发器不能用作 INSTEAD OF 触发器。 DDL 触发器不会为了响应影响本地或全局临时表和存储过程的事件而触发。
DDL 触发器不会创建特殊 inserted 和 deleted 表。
使用 EVENTDATA 函数捕获有关触发 DDL 触发器的事件的信息以及触发器引起的后续更改。
将为每个 DDL 事件创建多个触发器。
与数据作语言(DML)触发器不同,DDL 触发器的范围不局限于架构。 因此,函数(例如OBJECT_ID,OBJECT_NAME)OBJECTPROPERTYOBJECTPROPERTYEX不能用于查询有关 DDL 触发器的元数据。 请改用目录视图。
服务器范围的 DDL 触发器显示在 SQL Server Management Studio 对象资源管理器的“触发器”文件夹中。 此文件夹位于 “服务器对象” 文件夹下。 数据库范围内的 DDL 触发器显示在“数据库触发器”文件夹中。 此文件夹位于相应数据库的 “可编程性” 文件夹下。
重要说明
触发器内部的恶意代码可以在升级后的权限下运行。 有关如何帮助减少此威胁的详细信息,请参阅 管理触发器安全性。
DDL 触发器范围
在响应当前数据库或服务器上处理的 Transact-SQL 事件时,可以触发 DDL 触发器。 触发器的范围取决于事件。 例如,创建用于响应 CREATE_TABLE 事件的 DDL 触发器可以在数据库中或服务器实例上发生 CREATE_TABLE 事件时执行操作。 创建来响应 CREATE_LOGIN 事件而触发的 DDL 触发器只能在服务器实例中发生 CREATE_LOGIN 事件时触发。
在以下示例中,DDL 触发器safety会在数据库中发生DROP_TABLE或ALTER_TABLE事件时触发。
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 语句的文本。 有关如何与 DDL 触发器一起使用 EVENTDATA 的详细信息,请参阅 “使用 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;
本文后面的选择触发 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 触发器
可以安排在运行一个或多个特定 Transact-SQL 语句后触发 DDL 触发器。 在前面的示例中,触发器 safety 将在发生任何 DROP_TABLE 或 ALTER_TABLE 事件后触发。 有关可指定激发 DDL 触发器的 Transact-SQL 语句的列表,请参阅 DDL 事件。
选择预定义的 DDL 语句组以触发 DDL 触发器
可以在执行属于一组预定义的相似事件的任何 Transact-SQL 事件后激发 DDL 触发器。 例如,如果希望运行任何CREATE TABLE或ALTER TABLEDROP TABLE语句后触发 DDL 触发器,则可以在CREATE TRIGGER语句中指定FOR DDL_TABLE_EVENTS。 运行后 CREATE TRIGGER ,事件组涵盖的事件将添加到 sys.trigger_events 目录视图。
在 SQL Server 2005(9.x)中,如果在事件组上创建了触发器, sys.trigger_events 则不包括有关事件组的信息, sys.trigger_events 仅包含有关该组涵盖的各个事件的信息。 sys.trigger_events 保留有关创建触发器的事件组以及事件组所涵盖的各个事件的元数据。 因此,对事件组涵盖的事件所做的更改不适用于在 SQL Server 2005(9.x)中创建的 SQL Server 最新版本中的 DDL 触发器。
有关可用于 DDL 触发器的预定义 DDL 语句组、事件组涵盖的特定语句以及可以对这些事件组进行编程的范围的列表,请参阅 DDL 事件组。
相关任务
| 任务 | 文章 |
|---|---|
| 介绍如何创建、修改、删除或禁用 DDL 触发器。 | 实现 DDL 触发器 |
| 介绍如何创建 CLR DDL 触发器。 | 创建 CLR 触发器 |
| 介绍如何返回有关 DDL 触发器的信息。 | 获取有关 DDL 触发器的信息 |
介绍如何使用 EVENTDATA 函数返回有关触发 DDL 触发器的事件的信息。 |
使用 EVENTDATA 函数 |
| 介绍如何管理触发器安全性。 | 管理触发器安全性 |