Come ottenere il testo della procedura prima di modificare dal trigger DDL
-
19-09-2019 - |
Domanda
Sto creando un trigger per tracciare come è stato il testo della procedura ALTER
ed.
All'interno di un trigger DDL di database, è possibile accedere al testo della procedura corrente attraverso /EVENT_INSTANCE/TSQLCommand
.
Anche dopo aver indagato EVENTDATA()
, non conteneva valori per la precedente definizione di procedura prima ALTER
.
C'è un modo per recuperare il testo precedente come il modo in cui è possibile accedere ai valori eliminati nei trigger DML usando DELETED
tavolo?
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
Soluzione
Il grilletto funziona dopo che la modifica è stata apportata, quindi per quanto posso dire non c'è accesso ai valori "prima". EventData () è definito e non è previsto per "precedente". Di conseguenza, dovrai semplicemente registrare il valore corrente nel registro. Tuttavia, se prepopoli il tuo registro con questo 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'
Potresti usare il grilletto e avere ancora un quadro completo di tutte le modifiche. Il tuo registro avrebbe tutte le versioni precedenti e la versione corrente di ciascuna procedura. Potresti usare la mia versione del grilletto (vedi sotto), dove avresti accesso ad alcune delle altre colonne di sys.objects e sys.sql_modules, come:
uses_ansi_nulls
uses_quoted_identifier
is_schema_bound
null_on_null_input
principal_id
che potrebbe essere utile anche a registrare. Versione 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