Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8329841
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 9, 20262026-06-09T01:55:47+00:00 2026-06-09T01:55:47+00:00

I have an UPDATE trigger that produces INSERTED and DELETED table like this: INSERTED

  • 0

I have an UPDATE trigger that produces INSERTED and DELETED table like this:

INSERTED

Id  Name    Surname
1   Stack   Overflow
2   Luigi   Saggese

DELETED

Id  Name    Surname
1   Stacks  Overflow
2   Luigi   Sag

I want to capture this update to a log table. My Log table (that is global for all tables) is like this (then I must process my INSERTED and DELETED table):

Id_Table    Table_Key_Value   Id_Value   Old_Value  New_Value
12345               1          4556645    Stack      Stacks
12345               1           544589   Overflow   Overflows
12345               2           544589   Saggese       Sag

Id_Table is the table’s system object_id where I have performed the UPDATE statement, Table_Key_Value is the value of the primary key of the UPDATEd columns, Id_Value is a custom ID I mapped to each column in each table. A column’s data is logged only if the column is changed by the UPDATE.

I have thought of 2 ways to do this:

  1. Performing a SELECT on the table, once for each column:

    INSERT INTO LOG (Id_Table, Table_Key_Value, Id_Value,Old_Value, New_Value)
       SELECT 12345, Id, 4556645, D.Name, I.Name
       FROM INSERTED I 
       INNER JOIN DELETED D ON I.ID = D.ID
       WHERE D.Name <> I.Name
    
       union
    
       SELECT 12345, Id, 544589, D.Surname, I.Surname
       FROM INSERTED I 
       INNER JOIN DELETED D ON I.ID = D.ID
       WHERE D.Surname <> I.Surname
    
  2. Performing a single select against a UDF:

    SELECT CustomFunction(12345,Id, I.Name, D.Name, I.Surname, D.Surname) 
    FROM INSERTED I  
    INNER JOIN DELETED D ON I.ID = D.ID
    
    **CustomFunction** (_Id_Table,_Table_Key_Value, _Old_Value_Name, _New_Value_Name, _Old_Value_Surname, _New_Value_Surname)
    
    INSERT INTO LOG(Id_Table, Table_Key_Value, Id_Value,Old_Value, New_Value)
    VALUES(_Id_Table,_Table_Key_Value, 4556645, _Old_Value_Name, _New_Value_Name)
    
    INSERT INTO LOG(Id_Table, Table_Key_Value, Id_Value,Old_Value, New_Value)
    VALUES(_Id_Table,_Table_Key_Value, 544589, _Old_Value_Surname, _New_Value_Surname)
    

Are there other ways to do this? What is most efficient and maintainable way?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-09T01:55:49+00:00Added an answer on June 9, 2026 at 1:55 am

    Before answering, let me first say that I don’t think it is best to log all tables to a single table. If your database grows you could end up with serious contention on the Log table. Plus, all your data has to be changed to varchar or sql_variant in order to be put in the same column, forcing it to take up more space. I also think that logging each updated column to a separate row (skipping columns that aren’t updated) is going to make it very hard for you to query. Do you know how to pull all that data together to actually get a composite and sensible view of each row’s changes, when, and by whom? Having one log table per table is, in my opinion, going to be much easier. Then you won’t have the problems you’re experiencing trying to make it work.

    Also, did you know about SQL Server 2008 Change Data Capture? Use that instead, if you are using the Enterprise or Developer editions of SQL Server!

    Aside from that issue, you can do what you want with a logical UNPIVOT (performing your own version of it). You can’t really use the Native SQL 2005 UNPIVOT because you have two target columns, not one. Here’s an example for SQL Server 2005 and up using CROSS APPLY to perform the UNPIVOT:

    INSERT INTO dbo.LOG (Id_Table, Table_Key_Value, Id_Value, Old_Value, New_Value)
    SELECT 12345, I.Id, X.Id_Value, X.Old_Value, X.New_Value
    FROM
       INSERTED I 
       INNER JOIN DELETED D ON I.ID = D.ID
       CROSS APPLY (
          SELECT 4556645, D.Name, I.Name
          UNION ALL SELECT 544589, D.Surname, I.Surname
        ) X (Id_Value, Old_Value, New_Value)
    WHERE
       X.Old_Value <> X.New_Value
    

    Here’s a more generic method for SQL 2000 or other DBMSes (should theoretically work in Oracle, MySQL, etc. — for Oracle add FROM DUAL to each SELECT in the derived table):

    INSERT INTO dbo.LOG (Id_Table, Table_Key_Value, Id_Value, Old_Value, New_Value)
    SELECT *
    FROM (
       SELECT
          12345,
          I.Id,
          X.Id_Value,
          CASE X.Id_Value
             WHEN 4556645 THEN D.Name
             WHEN 544589 THEN D.Surname
          END Old_Value,
          CASE X.Id_Value
             WHEN 4556645 THEN I.Name
             WHEN 544589 THEN I.Surname
          END New_Value   
       FROM
          INSERTED I 
          INNER JOIN DELETED D ON I.ID = D.ID
          CROSS JOIN (
             SELECT 4556645
             UNION ALL SELECT 544589
          ) X (Id_Value)
    ) Y
    WHERE
       Y.Old_Value <> Y.New_Value
    

    SQL Server 2005 and up do have the native UNPIVOT command, though in general, even when UNPIVOT will work, I like using CROSS APPLY instead because there is more flexibility to do what I want. Specifically, the native UNPIVOT command isn’t workable here because UNPIVOT can only target a single destination column, but you need two (Old_Value, New_Value). Concatenating the two columns into a single value (and separating later) is not good; creating a meaningless row correlator value to PIVOT with afterward is not good, and I can’t think of another way to do it that’s not a variation on those two. The CROSS APPLY solution is truly going to be the best for you to match the exact log table structure you’ve described.

    Compared to my queries here, your method #1 will not perform as well (in a ratio of about {the number of columns}:1 worse performance). Your method #2 is a good idea but still suboptimal because calling a UDF has a large overhead, plus then you have to loop over each row (shudder).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a table trigger like below: CREATE OR REPLACE TRIGGER PAT_BUR_DOB_TRG BEFORE UPDATE
I'd like to create a trigger that writes to a history table with inserted
I have a trigger on update of a table that inserts into another table.
I have an update statement in a stored procedure that looks generally like this:
I have a BEFORE UPDATE trigger on one table. Now in that trigger, I
I have a trigger that executes a function on table insert or update. It
I have a trigger for insert/update/delete. That is working fine. Also, I need the
We have created a table with a trigger that updates a ModifiedDate field in
I have a search button tied to an update panel as a trigger like
I have a table where on a single record update, a trigger adds a

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.