2017-06-08 9 views
0

テーブルに多数のフィールドがあり、別のテーブルのinsert-update-deleteを監査しようとしています。SQL Triggerを使用して古い値と新しい値を取得する方法は?

私が選んだ正確なフィールドの値を得るという問題があります。

私はこのコードを書いており、正確なフィールドの古い値と新しい値を得ることを期待しています。

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の能力はありません。

編集:あなたはアーキテクチャを変更できないというご意見をお読みください。私は、テーブルがリモートで頻繁に使用されている場合、大きな問題を引き起こすこのようなトリガーを持つ代替方法があるからです。カーソルの外側に個々の挿入物を置いても、あなたはひどく噛まれて、あなたが生まれたことがないことを望みます。 msごとに、トリガが実行され、ロック競合(またはさらに悪いデッドロック)のリスクが指数関数的に増加します。

関連する問題