2010-11-06 206 views
6

无论何时在主表“Table1”中发生插入,更新或删除操作,我都希望在审计表中插入行 - - 哪一列更改/插入无关紧要。我也想在插入,更新或删除时添加I,U或D.对于插入和删除,我检查插入和删除表中是否存在行。什么是最好的方式来更新。插入,更新,删除的触发器

我的插入代码,并删除是:

CREATE TRIGGER [dbo].[tr_Table1_InsertUpdate_Table1History_Insert] 
ON [dbo].[Table1] 
FOR INSERT, DELETE, UPDATE 

AS 
BEGIN 
IF EXISTS(SELECT * FROM Inserted) 
BEGIN 
    INSERT INTO Table1History(...., ModificationType) 
    SELECT ..., 'I' 
    FROM Inserted 
END 


IF EXISTS(SELECT * FROM Deleted) 
BEGIN 
    INSERT INTO Table1History(..., ModificationType) 
    SELECT ..., 'D' 
    FROM Deleted 
END 

END 
GO 

请帮助!

回答

5

对于更新,行的原始值将被添加到删除的表中,并且该行的新值将被添加到插入的表中。因此,识别插入,删除和更新,你会做以下

  • 插件 - 从插入取得的行不在删除
  • 删除 - 已删除未在插入得到的行。
  • 更新 - 获取在两种插入行和删除
+0

谢谢!也会尝试AutoAudit。 – 2010-11-07 00:32:52

4

您是否考虑使用AutoAudit

AutoAudit是SQL Server(2005,2008) 代码生成工具,创建审计 线索触发与:

  • 创,CreatedBy,修改,ModifiedBy和RowVersion (增加INT)表列
  • 插入事件记录到审核表
  • 更新新旧值记录到审计表
  • 删除日志一LL最终值给审计tbale
  • 视图来重建被删除的行
  • UDF重构行历史
  • 架构审计触发追踪模式更改
  • 重新代码一族触发器时ALTER TABLE更改表
5

下面是ApexSQL Audit

这不是一个便宜的工具,但你也许可以用它在试用模式,以产生触发的例子把事做好。

注意INSERT INTO dbo.AUDIT_LOG_DATA部分,并对要审核的每一列重复该操作。

在后台有两个表格用于存储数据和多个存储过程,但这会让您朝着正确的方向前进。

CREATE TRIGGER [dbo].[tr_d_AUDIT_TableName] 
ON [dbo].[TableName] 
FOR DELETE 
NOT FOR REPLICATION 
AS 
BEGIN 
DECLARE 
    @IDENTITY_SAVE    varchar(50), 
    @AUDIT_LOG_TRANSACTION_ID  Int, 
    @PRIM_KEY    nvarchar(4000), 
    [email protected]_NAME    nvarchar(4000), 
    @ROWS_COUNT    int 

SET NOCOUNT ON 


Select @ROWS_COUNT=count(*) from deleted 
Set @IDENTITY_SAVE = CAST(IsNull(@@IDENTITY,1) AS varchar(50)) 

INSERT 
INTO dbo.AUDIT_LOG_TRANSACTIONS 
(
    TABLE_NAME, 
    TABLE_SCHEMA, 
    AUDIT_ACTION_ID, 
    HOST_NAME, 
    APP_NAME, 
    MODIFIED_BY, 
    MODIFIED_DATE, 
    AFFECTED_ROWS, 
    [DATABASE] 
) 
values(
    'TableName', 
    'dbo', 
    3, -- ACTION ID For DELETE 
    CASE 
     WHEN LEN(HOST_NAME()) < 1 THEN ' ' 
     ELSE HOST_NAME() 
    END, 
    CASE 
     WHEN LEN(APP_NAME()) < 1 THEN ' ' 
     ELSE APP_NAME() 
    END, 
    SUSER_SNAME(), 
    GETDATE(), 
    @ROWS_COUNT, 
    'DatabaseName' 
) 


Set @AUDIT_LOG_TRANSACTION_ID = SCOPE_IDENTITY() 

INSERT 
INTO dbo.AUDIT_LOG_DATA 
(
    AUDIT_LOG_TRANSACTION_ID, 
    PRIMARY_KEY_DATA, 
    COL_NAME, 
    OLD_VALUE_LONG, 
    DATA_TYPE 
    , KEY1 
) 
SELECT 
    @AUDIT_LOG_TRANSACTION_ID, 
    convert(nvarchar(1500), IsNull('[Order_ID]='+CONVERT(nvarchar(4000), OLD.[Order_ID], 0), '[Order_ID] Is Null')), 
    'Order_ID', 
    CONVERT(nvarchar(4000), OLD.[Order_ID], 0), 
    'A' 
    , CONVERT(nvarchar(500), CONVERT(nvarchar(4000), OLD.[Order_ID], 0)) 
FROM deleted OLD 
WHERE 
    OLD.[Order_ID] Is Not Null 
END