So erhalten Sie Prozedurtext, bevor Sie sich vom DDL -Trigger ändern
-
19-09-2019 - |
Frage
Ich erstelle einen Auslöser, um zu verfolgen, wie der Prozedurtext war ALTER
ed.
In einem Datenbank -DDL -Auslöser können Sie über den aktuellen Prozedurtext übertragen /EVENT_INSTANCE/TSQLCommand
.
Auch nach Untersuchung EVENTDATA()
, Es enthielt keine Werte für die vorherige Definition des Verfahrens zuvor ALTER
.
Gibt es eine Möglichkeit, früheren Text abzurufen, wie es möglich ist, gelöschte Werte in DML -Triggern mithilfe zuzugreifen DELETED
Tisch?
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
Lösung
Der Auslöser läuft nach der Änderung, soweit ich das erkennen kann, dass kein Zugriff auf die "Bevor" -Werte besteht. Die EventData () ist definiert und es gibt keine Bestimmung für "vorher". Infolgedessen müssen Sie den aktuellen Wert im Protokoll nur aufzeichnen. Wenn Sie jedoch Ihr Protokoll mit diesem Befehl vorpopulieren:
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'
Sie können Ihren Auslöser verwenden und dennoch ein vollständiges Bild von allen Änderungen haben. Ihr Protokoll würde alle vorherigen Versionen sowie die aktuelle Version jedes Prozedur haben. Sie können meine Version des Triggers verwenden (siehe unten), wo Sie Zugriff auf einige der anderen Spalten von sys.objects und sysql_modules haben, wie:
uses_ansi_nulls
uses_quoted_identifier
is_schema_bound
null_on_null_input
principal_id
das könnte auch praktisch für Protokollierung sein. Alternative Version:
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