2017-06-08 136 views
0

我在表中有很多字段,我试图审计任何插入 - 更新 - 在另一个表中删除。如何使用SQL触发器获取旧值和新值?

我只是有一个问题,得到我选择的确切领域的价值。

我写了这段代码,我希望得到一个确切字段的旧值和新值。

DECLARE @ColName NVARCHAR(225) , 
     @FieldID INT; 
    DECLARE columnCursor CURSOR 
    FOR 
     SELECT COLUMN_NAME 
     FROM INFORMATION_SCHEMA.COLUMNS 
     WHERE TABLE_NAME = 'acc_Account' 
       AND TABLE_SCHEMA = 'dbo'; 

    DECLARE @deleted_colmn INT; 

    DECLARE CurDB CURSOR 
    FOR 
     SELECT @deleted_colmn 
     FROM #Deleted; 


    OPEN columnCursor; 

    FETCH NEXT FROM columnCursor INTO @ColName; 

    WHILE (@@FETCH_STATUS <> -1) 
     BEGIN 



      --OPEN CurDB; 
      --FETCH NEXT FROM CurDB INTO @deleted_colmn; 

      SET @FieldID = (SELECT TOP 1 
            FieldID 
          FROM fld_Field 
          WHERE fld_Field.FieldName = @ColName 
          ); 


      SET @newvalue = (SELECT TOP 1 
             @ColName 
           FROM  Inserted 
           WHERE  @ColName = @ColName 
          ); 
      SET @oldvalue = (SELECT TOP 1 
             @ColName 
           FROM  Deleted 
       IF @newvalue <> @oldvalue 
       BEGIN 

        INSERT INTO dbo.utl_Audit_Trail_Field 
          (AuditTrailID , 
           FieldID , 
           OldValue , 
           NewValue , 
           CreatedDate , 
           CreatedUserID , 
           UpdatedDate , 
           UpdatedUserID 
          ) 
        VALUES (@AuditTrailID , -- AuditTrailID - bigint 
           @FieldID , -- FieldID - bigint 
           @oldvalue , -- OldValue - nvarchar(1000) 
           @newvalue , -- NewValue - nvarchar(1000) 
           @CreatedDate , -- CreatedDate - datetime 
           @CreatedUserID , -- CreatedUserID - bigint 
           @CreatedDate , -- UpdatedDate - datetime 
           @CreatedUserID -- UpdatedUserID - bigint 
          ); 

       END; 

      FETCH NEXT FROM columnCursor INTO @ColName; 

     END;    WHERE  @ColName = @ColName 

          ); 
+4

[首先阅读有关删除和插入的文档](https://docs.microsoft.com/en-us/sql/relational-databases/triggers/use-the-inserted-and-deleted-tables) 希望这可以帮助! –

+1

@BogdanSahlean他们不会在所有教程中不提及我,我是一个很好的例子。 ;-) –

+1

从来没有(我的意思是永远)在触发器中使用光标。永远。这样做是一种很好的方式,可以让一个完美健康的RDBMS尖叫到膝盖上,乞求怜悯。 –

回答

1

反思你的建筑。试图单独检测表格中的变化并分别存储每个表格都是一种灾难。

只需在审计表中存储Deleted表的全部内容,然后确保压缩表以减少大量重复使用的空间量。

磁盘存储空间很便宜,CPU功耗不大。

编辑:阅读你的评论,你不能改变架构;我想说你必须这样做,因为替代方案是有这样一个触发器,如果​​该表甚至被大量使用,将导致严重的问题。即使在游标之外进行单独的插入操作也会让你非常难过,你会希望自己从未出生过。对于触发器每运行一次,锁争用(甚至更糟,死锁)的风险呈指数增长。

相关问题