9

I have a trigger like below on user table to insert into the audit table with which column was updated and previous value:

ALTER TRIGGER [dbo].[trgAfterUpdate] ON [dbo].[tbl_User]
AFTER UPDATE
AS


    declare @fieldname varchar(128) ;
    declare @OldValue varchar(255);
    declare @CreateUser varchar(100) ;
    declare @User_Key int;

    select @CreateUser =i.user_name from deleted i; 
    SELECT @User_Key = i.user_key from inserted i;  

    if update(user_name)
      begin
          select @OldValue=j.user_name from deleted j;  
          set @fieldname = 'user_name';

            insert into tbl_Audit(user_key, field_name, previuos_Value, user_name)
            values(@User_Key ,@fieldname,@OldValue, @CreateUser);

      end

But my questions is I have like 100 fields on my table. I can't write 100 if conditions. And i need a suggestion how to use while loop in it, and how is it going to effect the performance.

Thanks

7
  • Why not just use XML for this? Commented Jun 11, 2013 at 18:36
  • 1
    Can you elaborate please? I am not sure how to insert into AUdit table using XML Commented Jun 11, 2013 at 18:41
  • Convert the entire row to XML using FOR XML and just store and XML column in your audit table. Commented Jun 11, 2013 at 18:42
  • But i want only updated column with previous data of that column...Some time out of 100 there may be 2 0r 3 fields updated. i need only those three fields Commented Jun 11, 2013 at 18:45
  • 1
    I don't think it's the ONLY way but it's probably the fastest way, for writes at least. Commented Jun 11, 2013 at 19:38

2 Answers 2

18

Try this one -

ALTER TRIGGER [dbo].[trgAfterUpdate] 

    ON [dbo].[tbl_User]
    AFTER UPDATE

AS BEGIN

    SET NOCOUNT ON
    SET XACT_ABORT ON

    DECLARE @DocumentUID UNIQUEIDENTIFIER

    DECLARE cur CURSOR FORWARD_ONLY READ_ONLY LOCAL FOR
        SELECT DocumentUID, ...
        FROM INSERTED

    OPEN cur

    FETCH NEXT FROM cur INTO @DocumentUID, ...

    WHILE @@FETCH_STATUS = 0 BEGIN

        DECLARE 
              @BeforeChange XML 
            , @AfterChange XML

        SELECT @BeforeChange = (
            SELECT *
            FROM DELETED
            WHERE [DocumentUID] = @DocumentUID
            FOR XML RAW, ROOT
        )
        , @AfterChange = (
            SELECT *
            FROM INSERTED
            WHERE [DocumentUID] = @DocumentUID
            FOR XML RAW, ROOT
        )

        INSERT INTO dbo.LogUser (DocumentUID, BeforeChange, AfterChange)
        SELECT @DocumentUID, @BeforeChange, @AfterChange

        -- your business logic 

        FETCH NEXT FROM cur INTO @DocumentUID, ...

    END

    CLOSE cur
    DEALLOCATE cur

END
Sign up to request clarification or add additional context in comments.

6 Comments

I don't need the complete row.I just need the field which has been modified and its previous value.Thanks for your reply though...
You only need find the difference between @BeforeChange and @AfterChange values.
Can you tell me the best way to compare the these two xml variables
these two xmls are totally different from normal xml file
|
-1

Try using query similar to this one – it will generate If statements for all columns of a given table.

Note: This is not fully tested and probably needs more adjustments but you see the idea behind it.

select 'if update(' + C.name + ')
  begin
      select @OldValue=j.' + C.name + ' from deleted j;  
      set @fieldname = ''' + C.name + ''';

        insert into tbl_Audit(user_key, field_name, previuos_Value, user_name)
        values(@User_Key ,@fieldname,@OldValue, @CreateUser);
  end'
from sys.all_columns C
inner join sys.tables T on C.object_id = T.object_id
where T.name = 'table_name' and T.schema_id = SCHEMA_ID('schema_name')

If wouldn’t go with while loop because it can probably cause perf issues…

2 Comments

so in your query i just need to replace table_name with my table name which is tbl_User right?
Can you tell me how to debug this trigger? It is not working on my table.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.