Cómo obtener el texto del procedimiento antes de alterar del disparador DDL
-
19-09-2019 - |
Pregunta
Estoy creando un gatillo para rastrear cómo ha sido el texto del procedimiento ALTER
ed.
Dentro de un desencadenador de DDL de la base de datos, es posible acceder al texto del procedimiento actual a través de /EVENT_INSTANCE/TSQLCommand
.
Incluso después de investigar EVENTDATA()
, no contenía valores para la definición anterior de procedimiento antes ALTER
.
¿Hay alguna forma de recuperar el texto anterior como cómo es posible acceder a los valores eliminados en los desencadenantes de DML usando DELETED
¿mesa?
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
Solución
El gatillo se ejecuta después de que se realizó el cambio, por lo que por lo que puedo decir, no hay acceso a los valores "antes". El evento EventData () se define y no hay ninguna disposición para "Anterior". Como resultado, tendrá que registrar el valor actual en el registro. Sin embargo, si prepobre su registro con 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'
Puede usar su disparador y aún así tener una imagen completa de todos los cambios. Su registro tendría todas las versiones anteriores, así como la versión actual de cada procedimiento. Puede usar mi versión del disparador (ver más abajo), donde tendría acceso a algunas de las otras columnas de sys.objects y sys.sql_modules, como:
uses_ansi_nulls
uses_quoted_identifier
is_schema_bound
null_on_null_input
principal_id
que podría ser útil para registrar también. versión 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