【问题标题】:How to get procedure text before ALTER from DDL trigger如何在 ALTER 之前从 DDL 触发器获取过程文本
【发布时间】:2009-10-05 18:17:43
【问题描述】:

我正在创建一个触发器来跟踪过程文本的ALTERed。

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

即使在调查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

【问题讨论】:

    标签: sql sql-server tsql ddl-trigger


    【解决方案1】:

    触发器在更改完成后运行,据我所知,无法访问“之前”值。已定义 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
    

    【讨论】:

    • @KM: "m.definition" 返回当前文本,而不是以前的文本。我也尝试过“sp_helptext”来返回值,但没有成功。
    • 谢谢,KM。我想我需要制定一个不同的计划才能按我的意愿工作。
    猜你喜欢
    • 1970-01-01
    • 2018-07-05
    • 2021-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-26
    • 1970-01-01
    相关资源
    最近更新 更多