如何在ALTER之前从DDL触发器获取过程文本

时间:2009-10-05 18:17:44

标签: sql sql-server tsql ddl-trigger

我正在创建一个触发器来跟踪过程文本的编辑方式ALTER

在数据库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

1 个答案:

答案 0 :(得分: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 o.Name=@EventData.value('(/EVENT_INSTANCE/ObjectName)[1]', 'nvarchar(max)')
                --modify as necessary AND type='P'

end
GO