Comment obtenir du texte de la procédure avant de modifier le déclencheur DDL
-
19-09-2019 - |
Question
Je crée un déclencheur pour suivre la façon dont le texte de la procédure a été ALTER
éd.
À l'intérieur d'un déclencheur DDL de base de données, il est possible d'accéder au texte de la procédure actuel via /EVENT_INSTANCE/TSQLCommand
.
Même après avoir enquêté EVENTDATA()
, il ne contenait pas de valeurs pour la définition précédente de la procédure avant ALTER
.
Existe-t-il un moyen de récupérer le texte précédent comme il est possible d'accéder DELETED
table?
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
La solution
Le déclencheur s'exécute après la modification, de sorte que pour autant que je sache, il n'y a pas d'accès aux valeurs "avant". L'EventData () est défini et il n'y a aucune disposition pour "précédent". En conséquence, vous devrez simplement enregistrer la valeur actuelle dans le journal. Cependant, si vous présentez votre journal avec cette commande:
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'
Vous pouvez utiliser votre déclencheur et avoir une image complète de toutes les modifications. Votre journal aurait toutes les versions précédentes ainsi que la version actuelle de chaque procédure. Vous pouvez utiliser ma version du déclencheur (voir ci-dessous), où vous auriez accès à certaines des autres colonnes de SYS.Objects et Sys.SQL_Modules, comme:
uses_ansi_nulls
uses_quoted_identifier
is_schema_bound
null_on_null_input
principal_id
Ce qui pourrait également être pratique pour se connecter. Version alternative:
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