EVENTDATA (Transact-SQL)

返回有关服务器或数据库事件的信息。激发事件通知时将调用 EVENTDATA,并且结果返回到指定的 Service Broker。还可以在 DDL 或登录触发器正文的内部使用 EVENTDATA。

主题链接图标Transact-SQL 语法约定

语法

EVENTDATA( )

注释

只有直接在 DDL 或登录触发器内部引用 EVENTDATA 时,EVENTDATA 才会返回数据。如果 EVENTDATA 由其他例程调用(即使这些例程由 DDL 或登录触发器进行调用),将返回 NULL。

在隐式或显式调用 EVENTDATA 的事务提交或回滚之后,EVENTDATA 所返回的数据将无效。

注意事项注意

EVENTDATA 返回 XML 数据。该数据将以 Unicode 的形式(其中每个字符包含 2 个字节)发送到客户端。以下 Unicode 码位可以在 EVENTDATA 所返回的 XML 中使用:

0x0009

0x000A

0x000D

>= 0x0020 && <= 0xD7FF

>= 0xE000 && <= 0xFFFD

某些可以在 Transact-SQL 标识符和数据中使用的字符不能或不允许在 XML 中使用。其码位没有显示在前面列表中的字符或数据将映射为问号 (?)。

返回的架构

EVENTDATA 返回类型为 xml 的值。默认情况下,所有事件的架构定义都安装在以下目录:C:\Program Files\Microsoft SQL Server\100\Tools\Binn\schemas\sqlserver\2006\11\events\events.xsd。

此外,事件架构还发布在 Microsoft SQL Server XML 架构网页。

若要提取任何特定事件的架构,请搜索复杂类型 EVENT_INSTANCE_<event_type> 的架构。例如,若要提取 DROP_TABLE 事件的架构,请搜索 EVENT_INSTANCE_DROP_TABLE 的架构。

示例

A. 在 DDL 触发器中查询事件数据

以下示例创建 DDL 触发器,以防止在数据库中创建新表。通过对 EVENTDATA 生成的 XML 数据使用 XQuery,可以捕获激发触发器的 Transact-SQL 语句。有关详细信息,请参阅XQuery 语言参考(数据库引擎)

注意注意

当您通过使用 SQL Server Management Studio 中的“以网格显示结果”来查询 <TSQLCommand> 元素时,命令文本中的分行符不会出现。请改用“以文本格式显示结果”

USE AdventureWorks2008R2;
GO
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
;
GO
--Test the trigger.
CREATE TABLE NewTable (Column1 int);
GO
--Drop the trigger.
DROP TRIGGER safety
ON DATABASE;
GO
注意注意

如果需要返回事件数据,我们建议使用 XQuery value() 方法而不是 query() 方法。query() 方法可在输出中返回 XML 和以“and”符转义的回车符和换行符 (CR/LF) 实例,而 value() 方法无法在输出中呈现 CR/LF 实例。

B. 创建事件数据在 DDL 触发器中的日志表

以下示例创建用于存储所有数据库级事件的相关信息的表,并在表中填充 DDL 触发器。通过对 EVENTDATA 生成的 XML 数据使用 XQuery,可以捕获事件类型和 Transact-SQL 语句。

USE AdventureWorks2008R2;
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
--Drop the trigger.
DROP TRIGGER log
ON DATABASE;
GO
--Drop table ddl_log.
DROP TABLE ddl_log;
GO

C. 根据部分架构验证事件实例

下面的示例根据 EVENTDATA 返回的架构验证 DROP_TABLE 事件。

IF EXISTS (SELECT * FROM sys.xml_schema_collections WHERE name='EventsXML')
DROP XML SCHEMA COLLECTION EventsXML ;
GO

DECLARE @x xml
SET @x = (SELECT * FROM OPENROWSET(BULK 'c:\Program Files\Microsoft SQL Server\90\Tools\Binn\schemas\sqlserver\2006\11\events\events.xsd', single_clob) AS x)
CREATE XML SCHEMA COLLECTION EventsXML AS @x ;
GO

DECLARE @x xml(XSDEVENTS)
DECLARE @y xml
DECLARE @n nvarchar(max)

SELECT @y = EVENTDATA()
SELECT @n = @y
SELECT @n = REPLACE(@n, '<EVENT_INSTANCE', '<EVENT_INSTANCE xmlns=''https://schemas.microsoft.com/sqlserver/2006/eventdata'' xmlns:xsi=''http://www.w3.org/2001/XMLSchema-instance'' xsi:type=''EVENT_INSTANCE_DROP_TABLE''')

SELECT @x = @n -- This causes the validation.