SQL Server 2005 包括对 Transact-SQL (T-SQL) 语言的几项重要改进。新增功能之一是一种新的触发器,它在数据定义语言 (DDL) 语句运行时激发。
CREATE TRIGGER ddlTrigger_ProcNamingConvention
ON DATABASE
AFTER CREATE_PROCEDURE, ALTER_PROCEDURE
AS
DECLARE @eventDataXml XML
SET @eventDataXml = EVENTDATA()
IF SUBSTRING(@eventDataXml.value('(//ObjectName)[1]',
'VARCHAR(200)'), 1, 2) = 'pr'
PRINT 'starts with pr'
ELSE
BEGIN
PRINT 'does not start with pr'
ROLLBACK TRANSACTION
END
GO
请注意,这段代码中的 DDL 触发器定义为,在当前数据库上创建或更改存储过程时激发。当触发器激发后,事件的数据会被捕获并存储在本地 XML 变量中。尽管这不是必要的,但如果您打算多次访问 eventdata 函数,这有助于使触发器更高效。然后,触发器会检查对象的名称是否以 pr 开头。如果是,则允许事务完成;如果不是,则回滚事务,并且存储过程将保持不变。在本例中,我知道 ObjectName 元素将包含存储过程的名称,因为仅在创建或更改存储过程时才会调用触发器。
<EVENT_INSTANCE>
<EventType>CREATE_PROCEDURE</EventType>
<PostTime>2005-10-20T00:52:16.160</PostTime>
<SPID>51</SPID>
<ServerName>MYDBSERVER</ServerName>
<LoginName>CAMELOT\jpapa</LoginName>
<UserName>dbo</UserName>
<DatabaseName>AdventureWorks</DatabaseName>
<SchemaName>dbo</SchemaName>
<ObjectName>test1</ObjectName>
<ObjectType>PROCEDURE</ObjectType>
<TSQLCommand>
<SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON"
QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE" />
<CommandText>create proc test1 as select getdate()</CommandText>
</TSQLCommand>
</EVENT_INSTANCE> |
显示执行以下命令后该触发器的事件数据:
create proc test1 as select getdate |
您还可以捕获事件数据,并将其完整存储到审核表的 XML 列中。另一个选择是抽出特定节点的内容,并将其单独存储。显然,实现视具体情况而定,但 DDL 触发器为您提供的选择有很多。使用 DDL 触发器时需要记住的一件事是,它们是同步操作的。由于是同步执行,触发器应该尽可能不执行费时的操作。否则,它们会对数据库服务器的性能造成负面影响。与 DML 触发器一样,应该将 DDL 触发器定义为仅执行所需的操作并快速完成。如果需要异步执行,可以使用 Service Broker 和 Event Notification 模型。