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
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 */