テーブルへの変更を監査するトリガーを作成しました。
CREATE TRIGGER [dbo].[iudt_AutoAuditChanges]
ON dbo.CPTCategoryMaster
AFTER INSERT,DELETE,UPDATE
AS
BEGIN
SET NOCOUNT ON;
Declare @v_AuditID bigint
IF OBJECT_ID('dbo.AutoAudit','U') IS NULL BEGIN
CREATE TABLE [dbo].[AutoAudit]
( [AuditID] bigint identity,
[AuditDate] DateTime,
[AuditUserName] varchar(128),
[TableName] varchar(128) NULL,
[OldContent] XML NULL,
[NewContent] XML NULL
)
ALTER TABLE dbo.AutoAudit ADD CONSTRAINT
PK_AutoAudit PRIMARY KEY CLUSTERED
(
[AuditID]
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [idx_AutoAudit_TableName_AuditDate] ON [dbo].[AutoAudit]
( [TableName] ASC,
[AuditDate] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
END
Select * Into #AuditDeleted from deleted
Select * Into #AuditInserted from inserted
While (Select COUNT(*) from #AuditDeleted) > 0 OR (Select COUNT(*) from #AuditInserted) > 0
Begin
INSERT INTO [dbo].[AutoAudit]
( [AuditDate], [AuditUserName], [TableName], [OldContent], [NewContent])
SELECT
GETDATE(),
SUSER_NAME(),
[TableName]=object_name([parent_obj]),
[OldContent]=CAST((SELECT TOP 1 * FROM #AuditDeleted D FOR XML RAW) AS xml),
[NewContent]=CAST((SELECT TOP 1 * FROM #AuditInserted I FOR XML RAW) AS xml)
FROM sysobjects
WHERE
[xtype] = 'tr'
and [name] = OBJECT_NAME(@@PROCID)
Set @v_AuditID = SCOPE_IDENTITY()
Delete from AutoAudit
Where AuditID = @v_AuditID
AND Convert(varchar(max),oldContent) = Convert(varchar(max),NewContent)
Delete top(1) from #AuditDeleted
Delete top(1) from #AuditInserted
End
END
これにより、次のようなXMLデータが生成されます。
row CPTCategoryId="1" CPTCategoryName="NEW CHARGE" Remarks="" Status="1" CreatedBy="11" CreatedDate="2014-05-01T12:50:16.947" ModifiedBy="11" ModifiedDate="2014-05-01T14:20:47.793" LockVersion="0"
列データ(CPTCategoryId, CPTCategoryName, Remarks
...など)グリッドビューで表示するには?または、この要件を実装するより良い方法はありますか?
行に挿入されたすべての列の値をキャッチして、他の監査データを保存するテーブルに保存できます。
ApexSQL Audit のようなサードパーティのツールがあり、そのようなトリガーを作成し、データ(古いものと新しいものの両方のUPDATE)をキャプチャし、レポートを表示します。
次の列を持つテーブルに行が挿入されたとき:
すべての列の値が個別の列として表示されます
あなたはここでより有用な情報を見つけることができます: SQL Serverデータベースの監査トリガー
免責事項:私はApexSQLでサポートエンジニアとして働いています
変更されたデータの画像の前後にXMLを挿入するというあなたのアイデアは本当に好きです。私見、それはtrigger
に十分な軽量ではありません。 WHILE
ループ全体を次のように変更しました(別の名前で申し訳ありません)
insert into audit (table_name, old_content, new_content)
select
@table_name,
case when d.table_id is null then null else (select d.* for xml raw) end,
case when i.table_id is null then null else (select i.* for xml raw) end
from inserted as i
full outer join deleted as d on i.table_id = d.table_id
詳細はgithubの yact にあります。
2016年7月11日更新
old_content
およびnew_content
列には、行の変更前イメージと変更後イメージのXML表現が含まれています。