Compare deleted and inserted table in SQL Server 2008

后端 未结 4 629
迷失自我
迷失自我 2020-12-21 16:56

I am new to SQL Server 2008 and I need advice from all of you. I want to find out the changed value in inserted and deleted tables of the SQL Serve

4条回答
  •  自闭症患者
    2020-12-21 17:28

    First: do NOT use a cursor inside a trigger - EVER!

    Second: to identify what fields were included in the update statement you can use: UPDATE() or COLUMNS_UPDATED()

    Note: This does NOT list the fields that have had their value changed, just the list of columns included in the SET portion of the UPDATE statement.

    Third: There are a variety of methods that you can use to audit changes to your tables (the accepted answer on Most efficient method to detect column change in MS SQL Server has a good list and guidelines on how to use, if you are using SQL Server Enterprise you could also look at using Change Data Capture

    Some example audit code I would use (where I want to record a column by column audit table):

    INSERT INTO AuditTable (ColumnChanged, OldValue, NewValue) /* I assume there are default columns logging who/when the change was done by? */
        SELECT 'ColumnA' as ColumnChanged, d.ColumnA, i.ColumnA
        FROM inserted i join deleted d ON d.PKID = i.PKID
        WHERE 
            /* both aren't null and the value has changed */
            (d.ColumnA IS NOT NULL AND i.ColumnA IS NOT NULL AND d.ColumnA != i.ColumnA) 
            /* it was null and now it isn't */
            OR (d.ColumnA IS NULL AND i.ColumnA IS NOT NULL) 
            /* it wasn't null and now it is */
            OR (d.ColumnA IS NOT NULL AND i.ColumnA IS NULL)
    UNION 
        SELECT 'ColumnB' as ColumnChanged, d.ColumnB, i.ColumnB
        FROM inserted i join deleted d ON d.PKID = i.PKID
        WHERE 
            /* both aren't null and the value has changed */
            (d.ColumnB IS NOT NULL AND i.ColumnB IS NOT NULL AND d.ColumnB != i.ColumnB) 
            /* it was null and now it isn't */
            OR (d.ColumnB IS NULL AND i.ColumnB IS NOT NULL) 
            /* it wasn't null and now it is */
            OR (d.ColumnB IS NOT NULL AND i.ColumnB IS NULL)
    ....  /* continuing for each column */
    

    It would be simpler (from a sql perspective and faster [due to less writes] to audit by row) ie:

    INSERT INTO AuditTable (OldValueA, NewValueA, OldValueB, NewValueB) 
    SELECT d.ColumnA, i.ColumnA, d.ColumnB, i.ColumnB
    FROM inserted i join deleted d ON d.PKID = i.PKID
    WHERE 
    /* same check for columnA */
        /* both aren't null and the value has changed */
        (d.ColumnA IS NOT NULL AND i.ColumnA IS NOT NULL AND d.ColumnA != i.ColumnA) 
        /* it was null and now it isn't */
        OR (d.ColumnA IS NULL AND i.ColumnA IS NOT NULL) 
        /* it wasn't null and now it is */
        OR (d.ColumnA IS NOT NULL AND i.ColumnA IS NULL)
    /* now check columnB */
        (d.ColumnB IS NOT NULL AND i.ColumnB IS NOT NULL AND d.ColumnB != i.ColumnB) 
        OR (d.ColumnB IS NULL AND i.ColumnB IS NOT NULL) 
        OR (d.ColumnB IS NOT NULL AND i.ColumnB IS NULL)
    ....  /* continuing for each column */
    

提交回复
热议问题