I have the following table:
DECLARE @TABLE_A TABLE (
id int identity,
name varchar(20),
start_date datetime,
end_date datetime,
details nvarchar(500),
copied_from int)
Users can clone a row and re-insert it into the same table, we record which row it's copied from. So if you have a row with ID = 1 and you copy all of its columns and re-insert it (from the UI) you get a new row with ID = 5 and copied_from field for the new row will have the value as 1.
After this users can update the new row values (ID 5 in this example), we needed a way to see the differences between the 2 rows. I have written the below to get the differences between the columns of ID 1 and ID 5.
DECLARE @id int = 5
DECLARE @TABLE_A TABLE (id int identity, name varchar(20), start_date datetime, end_date datetime, details nvarchar(500), copied_from int)
INSERT INTO @TABLE_A (name, start_date, end_date, details, copied_from)
SELECT 'Tom', '2017-01-01', '2017-02-01', '<p>this column can contain html mark up</p>', null UNION ALL
SELECT 'Tom', '2017-01-01', '2017-02-01', '<p>this column can contain html mark up</p>', null UNION ALL
SELECT 'Tom', '2017-01-01', '2017-02-01', '<p>this column can contain html mark up</p>', null UNION ALL
SELECT 'Tom', '2017-01-01', '2017-02-01', '<p>this column can contain html mark up</p>', null UNION ALL
SELECT 'John', '2017-01-01', '2017-02-01', '<p>this column can contain html mark up - changed</p>', 1
SELECT
'Name' AS column_name,
ISNULL(s.name, '') AS value_before,
ISNULL(t.name, '') AS value_after,
t.id,
t.copied_from
FROM @TABLE_A s
FULL OUTER JOIN @TABLE_A t ON s.id = t.copied_from
WHERE t.id = @id AND ISNULL(s.name, '') <> ISNULL(t.name, '')
UNION ALL
SELECT
'Details' AS column_name,
ISNULL(s.details, '') AS value_before,
ISNULL(t.details, '') AS value_after,
t.id,
t.copied_from
FROM @TABLE_A s
FULL OUTER JOIN @TABLE_A t ON s.id = t.copied_from
WHERE t.id = @id AND ISNULL(s.details, '') <> ISNULL(t.details, '')
.......
As you can see there is a self join on ID and COPIED_FROM fields and for each column I check to see if there is a difference.
This works but somehow I am not happy with the repeated UNIONS for each column, I was wondering if there is another way of achieving this?
Thanks
Try the below script, this may be help you. Using the
CASE WHEN
expression we can identify the column that are modified. But this will return only a single record with all the details (before value, after value and status- 1:modified/0:not).