我正在创建一个触发器来跟踪过程文本是如何被更改的.
在数据库DDL触发器内部,
可以通过/ EVENT_INSTANCE / TSQLCommand访问当前过程Text.
即使在调查了EVENTDATA()
之后,它也没有包含之前ALTER之前的程序定义的值.
有没有办法检索以前的文本,比如如何使用DELETED表访问DML触发器中的已删除值?
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()已定义,并且没有“previous”的规定.因此,您只需在日志中记录当前值.但是,如果使用此命令预填充日志:
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