代码之家  ›  专栏  ›  技术社区  ›  dance2die

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

  •  4
  • dance2die  · 技术社区  · 15 年前

    我正在创建一个触发器来跟踪过程文本 ALTER 预计起飞时间。

    在数据库DDL触发器中, 可以通过 /EVENT_INSTANCE/TSQLCommand .

    即使在调查之后 EVENTDATA() ,它不包含以前过程定义的值 改变 .

    是否有方法检索以前的文本,例如如何使用 DELETED 桌子?

    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 回复  |  直到 9 年前
        1
  •  2
  •   KM.    15 年前

    触发器在进行更改后运行,据我所知,没有访问“before”值的权限。已定义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_模块访问其他一些列,例如:

    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