使用 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。
注意: |
---|
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
注意: |
---|
若要返回事件数据,建议您使用 XQuery value() 方法来替代 query() 方法。query() 方法可在输出中返回 XML 和以“and”符转义的回车符和换行符 (CRLF) 实例,而 value() 方法无法在输出中呈现 CRLF 实例。 |
AdventureWorks 示例数据库还提供了类似的 DDL 触发器示例。若要获得示例,请使用 SQL Server Management Studio 找到 Database Triggers 文件夹。此文件夹位于 AdventureWorks 数据库的**“可编程性”文件夹下。右键单击 ddlDatabseTriggerLog 并选择“编写数据库触发器脚本为”**。默认情况下,DDL 触发器 ddlDatabseTriggerLog 处于禁用状态。
请参阅
概念
帮助和信息
更改历史记录
版本 | 历史记录 |
---|---|
2005 年 12 月 5 日 |
|