Как получить текст процедуры перед изменением с триггера DDL

StackOverflow https://stackoverflow.com/questions/1521598

Вопрос

Я создаю триггер, чтобы отслеживать, как был текст процедуры ALTERредакция

Внутри триггера DDL базы данных можно получить доступ к текущей процедуре через текст через /EVENT_INSTANCE/TSQLCommand.

Даже после расследования EVENTDATA(), он не содержал значений для предыдущего определения процедуры до ALTER.

Есть ли способ получить предыдущий текст, например, как можно получить доступ к удаленным значениям в DML -триггерах, используя 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
Это было полезно?

Решение

Триггер работает после того, как было внесено изменение, поэтому, насколько я могу судить, нет доступа к значениям «до». EventData () определено, и нет никаких положений для «предыдущего». В результате вам придется просто записать текущее значение в журнале. Однако, если вы предварительно заполните свой журнал с помощью этой команды:

    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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top