使用 EVENTDATA 函数

更新日期: 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

ms187909.Caution(zh-cn,SQL.90).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
ms187909.note(zh-cn,SQL.90).gif注意:
若要返回事件数据,建议您使用 XQuery value() 方法来替代 query() 方法。query() 方法可在输出中返回 XML 和以“and”符转义的回车符和换行符 (CRLF) 实例,而 value() 方法无法在输出中呈现 CRLF 实例。

AdventureWorks 示例数据库还提供了类似的 DDL 触发器示例。若要获得示例,请使用 SQL Server Management Studio 找到 Database Triggers 文件夹。此文件夹位于 AdventureWorks 数据库的**“可编程性”文件夹下。右键单击 ddlDatabseTriggerLog 并选择“编写数据库触发器脚本为”**。默认情况下,DDL 触发器 ddlDatabseTriggerLog 处于禁用状态。

请参阅

概念

设计 DDL 触发器

帮助和信息

获取 SQL Server 2005 帮助

更改历史记录

版本 历史记录

2005 年 12 月 5 日

新增内容:
  • 添加了有关针对 CREATE_SCHEMA 事件和任何相应 CREATE SCHEMA 定义的 <schema_element> 文本创建 DDL 触发器的注意事项。