更新日期: 2005 年 12 月 5 日
使用 EVENTDATA 函数,可以捕获有关激发 DDL 触发器的事件的信息。此函数返回 xml 值。XML 架构包括下列信息:
- 事件时间。
- 在执行触发器时,连接的系统进程 ID (SPID)。
- 激发触发器的事件类型。
根据事件类型,该架构还包括其他信息,例如事件在其中发生的数据库、发生事件的相关对象以及事件的 Transact-SQL 语句。有关详细信息,请参阅 EVENTDATA (Transact-SQL)。
例如,将在 AdventureWorks 示例数据库中创建以下 DDL 触发器:
CREATE TRIGGER safety 
ON DATABASE 
FOR CREATE_TABLE 
AS 
    PRINT 'CREATE TABLE Issued.'
    SELECT EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')
   RAISERROR ('New tables cannot be created in this database.', 16, 1) 
   ROLLBACK
;
然后运行以下 CREATE TABLE 语句:
    CREATE TABLE NewTable (Column1 int);
DDL 触发器中的 EVENTDATA() 语句将捕获不允许使用的 CREATE TABLE 语句文本。通过对 EVENTDATA 生成的 xml 数据使用 XQuery 语句以及检索 <CommandText> 元素来实现此操作。有关详细信息,请参阅针对 xml 数据类型的 XQuery。
| .gif) 注意: | 
|---|
| EVENTDATA 将捕获 CREATE_SCHEMA 事件的数据以及相应 CREATE SCHEMA 定义的 <schema_element>(如果存在)。此外,EVENTDATA 将 <schema_element> 定义识别为单独的事件。因此,针对 CREATE_SCHEMA 事件和由 CREATE_SCHEMA 定义的 <schema_element> 表示的事件创建的 DDL 触发器可能两次返回相同的事件数据,如 TSQLCommand数据。例如,针对 CREATE_SCHEMA 事件和 CREATE_TABLE 事件创建的 DDL 触发器,将运行下列批处理:CREATE SCHEMA s    CREATE TABLE t1 (col1 int)如果应用程序检索 CREATE_TABLE 事件的TSQLCommand数据,则注意,此数据可能出现两次:一次是在 CREATE_SCHEMA 事件发生时,另一次是在 CREATE_TABLE 事件发生时。请避免同时针对 CREATE_SCHEMA 事件和任何相应 CREATE SCHEMA 定义的 <schema_element> 文本创建 DDL 触发器,或将逻辑置于应用程序中,这样,同一事件就不会被处理两次。 | 
示例
您可以使用 EVENTDATA 函数来创建事件日志。在下面的示例中,创建了一个表来存储事件信息。然后,针对当任何数据库级 DDL 事件发生时,使用以下信息填充表的当前数据库创建 DDL 触发器:
- 事件时间(使用 GETDATE 函数)。
- 其会话上发生事件的数据库用户(使用 CURRENT_USER 函数)。
- 事件类型。
- 包括事件的 Transact-SQL 语句。
此外,通过对 EVENTDATA 生成的 xml 数据使用 XQuery 来捕获最后两项。
USE AdventureWorks;
GO
CREATE TABLE ddl_log (PostTime datetime, DB_User nvarchar(100), Event nvarchar(100), TSQL nvarchar(2000));
GO
CREATE TRIGGER log 
ON DATABASE 
FOR DDL_DATABASE_LEVEL_EVENTS 
AS
DECLARE @data XML
SET @data = EVENTDATA()
INSERT ddl_log 
   (PostTime, DB_User, Event, TSQL) 
   VALUES 
   (GETDATE(), 
   CONVERT(nvarchar(100), CURRENT_USER), 
   @data.value('(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(100)'), 
   @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(2000)') ) ;
GO
--Test the trigger
CREATE TABLE TestTable (a int)
DROP TABLE TestTable ;
GO
SELECT * FROM ddl_log ;
GO
| .gif) 注意: | 
|---|
| 若要返回事件数据,建议您使用 XQuery value() 方法来替代 query() 方法。query() 方法可在输出中返回 XML 和以“and”符转义的回车符和换行符 (CRLF) 实例,而 value() 方法无法在输出中呈现 CRLF 实例。 | 
AdventureWorks 示例数据库还提供了类似的 DDL 触发器示例。若要获得示例,请使用 SQL Server Management Studio 找到 Database Triggers 文件夹。此文件夹位于 AdventureWorks 数据库的**“可编程性”文件夹下。右键单击 ddlDatabseTriggerLog 并选择“编写数据库触发器脚本为”**。默认情况下,DDL 触发器 ddlDatabseTriggerLog 处于禁用状态。
请参阅
概念
帮助和信息
更改历史记录
| 版本 | 历史记录 | 
|---|---|
| 2005 年 12 月 5 日 | 
 |