DDLトリガーからALTERを変更する前に手順テキストを取得する方法
-
19-09-2019 - |
質問
手順テキストがどのようになったかを追跡するトリガーを作成しています ALTER
編
データベースDDLトリガー内では、現在の手順テキストにアクセスすることができます /EVENT_INSTANCE/TSQLCommand
.
調査した後でも EVENTDATA()
, 、以前の手順の以前の定義の値は含まれていませんでした ALTER
.
以前のテキストを取得する方法はありますか? DELETED
テーブル?
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()が定義されており、「前」の規定はありません。その結果、ログに現在の値を記録するだけです。ただし、このコマンドでログを事前に設定する場合:
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
所属していません StackOverflow