Pergunta

Estou criando um gatilho para rastrear como o texto do procedimento foi ALTERed.

Dentro de um gatilho DDL de banco de dados, é possível acessar o texto do procedimento atual por meio /EVENT_INSTANCE/TSQLCommand.

Mesmo depois de investigar EVENTDATA(), não continha valores para a definição anterior de procedimento antes ALTER.

Existe uma maneira de recuperar o texto anterior, como é possível acessar valores excluídos em gatilhos de DML usando DELETED tabela?

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
Foi útil?

Solução

O gatilho funciona após a alteração, tanto quanto eu sei, não há acesso aos valores "antes". O EventData () é definido e não há provisão para "anterior". Como resultado, você precisará apenas registrar o valor atual no log. No entanto, se você preparar seu log com este comando:

    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'

Você pode usar seu gatilho e ainda ter uma imagem completa de todas as alterações. Seu log teria todas as versões anteriores, bem como a versão atual de cada procedimento. Você pode usar minha versão do gatilho (veja abaixo), onde teria acesso a algumas das outras colunas do Sys.Objects e Sys.SQL_Modules, como:

uses_ansi_nulls
uses_quoted_identifier
is_schema_bound
null_on_null_input
principal_id

o que pode ser útil para registrar também. versão alternativa:

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top