2009-10-05 72 views
4

获得过程文本我创建一个触发器来跟踪过程文本已经ALTER版。如何改变之前,DDL触发器

在数据库DDL触发器中, 可以通过/EVENT_INSTANCE/TSQLCommand访问当前过程文本。

即使在调查EVENTDATA()之后,它也没有包含ALTER之前过程定义的值。

有没有办法检索以前的文本,比如如何使用DELETED表来访问DML触发器中的删除值?

create trigger trgDDLAuditQuery 
on database 
for  alter_procedure 
as 
begin 
    set nocount on; 

    declare @data xml 
    set @data = EVENTDATA() 

    insert dbo.tblQueryAudit(ObjectName, TSQLCommand) 
    select @data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'nvarchar(256)'), 
     --; Only gets currently changed procedure text, not previous one 
     @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(max)') 
end 
GO 

回答

2

触发运行更改之后,所以据我可以告诉有是“之前”值的访问权限。 EVENTDATA()被定义并且没有为“previous”提供。因此,您只需在日志中记录当前值即可。但是,如果预填充日志使用此命令:

INSERT INTO dbo.tblQueryAudit 
      (ObjectName, TSQLCommand) 
    SELECT 
     o.Name,m.definition 
     FROM sys.objects     o 
      INNER JOIN sys.sql_modules m ON o.object_id=m.object_id 
     WHERE type='P' 

,你可以用你的触发器,而且还有所有变化的完整画面。您的日志将具有所有以前的版本以及每个过程的当前版本。你可以使用我的版本触发(见下文),在那里你将不得不从一些sys.objects中和sys.sql_modules其他列的访问,如:

uses_ansi_nulls 
uses_quoted_identifier 
is_schema_bound 
null_on_null_input 
principal_id 

这可能是得心应手的日志,以及。替代版本:

CREATE trigger trgDDLAuditQuery 
on database 
for    alter_procedure 
as 
begin 
    set nocount on; 

    DECLARE @EventData  xml 
    SET @EventData=EVENTDATA() 

    INSERT INTO dbo.tblQueryAudit 
      (ObjectName, TSQLCommand) --hope you have datetime column that defaults to GETDATE() 
     SELECT 
      o.Name,m.definition 
      FROM sys.objects     o 
       INNER JOIN sys.sql_modules m ON o.object_id=m.object_id 
      WHERE [email protected]('(/EVENT_INSTANCE/ObjectName)[1]', 'nvarchar(max)') 
       --modify as necessary AND type='P' 

end 
GO 
+0

@KM:“m.definition”返回当前文本,而不是以前的文本。我也尝试过“sp_helptext”来返回值,但没有成功。 – Sung 2009-10-05 19:01:02

+0

谢谢,KM。我想我需要制定一个不同的计划,以便按照我的要求工作。 – Sung 2009-10-06 13:12:27