Assuming EmployeeId
is the PRIMARY KEY or a unique key on the Employees
table, and the value of the EmployeeId wasn't updated:
IF NOT UPDATE(EmployeeId)
INSERT INTO ChangeLog (EmpId, OldRate, NewRate)
SELECT d.EmployeeId
, d.Pay
, i.Pay
FROM deleted d
JOIN inserted i
ON i.EmployeeId = d.EmployeeId
;
Note that if the value of EmployeeId
is changed, this insert wouldn't necessarily insert a row to the ChangeLog table. Consider a query of the form:
UPDATE Employees SET Pay = 7, EmployeeId = 757 WHERE EmployeeId = 42
If that is successful, we expect the deleted
table will contain
EmployeeId Pay somecol ...
---------- --- ------- ---
42 4 someval
and inserted table will contain
EmployeeId Pay somecol ...
---------- --- ------- ---
757 7 someval ...
A couple of queries using an anti-join pattern would pick up those changes which would be missed by our first query...
-- deleted with no matching inserted
INSERT INTO ChangeLog (EmpId, OldRate, NewRate)
SELECT d.EmployeeId
, d.Pay
, NULL
FROM deleted d
LEFT
JOIN inserted i
ON i.EmployeeId = d.EmployeeId
WHERE i.EmployeeId IS NULL
;
-- inserted with no matching deleted
INSERT INTO ChangeLog (EmpId, OldRate, NewRate)
SELECT i.EmployeeId
, NULL
, i.Pay
FROM inserted i
LEFT
JOIN deleted d
ON d.EmployeeId = i.EmployeeId
WHERE d.EmployeeId IS NULL
;
But... that falls down if we "swap" EmployeeId values. Consider rows with EmployeeId values of 757 and 42 exist in the table, and we issue a statement like this:
UPDATE Employees
SET EmployeeId = CASE WHEN EmployeeId = 42 THEN 757
WHEN EmployeeId = 757 THEN 42
END
, Pay = CASE WHEN EmployeeId = 42 THEN 4
WHEN EmployeeId = 757 THEN 7
END
WHERE EmployeeId IN (42,757)
With that, the rows in the inserted
and deleted
tables will be "cross wired"... EmployeeId values will match, but will match a different row. So we probably want to test whether an UPDATE statement attempted to assign a new value to EmployeeId column, so we can take the appropriate action.
We might be better off just recording the changes...
INSERT INTO ChangeLog (action, empid, pay )
SELECT 'update old', EmployeeId, Pay
FROM deleted
;
INSERT INTO ChangeLog (action, empid, pay )
SELECT 'update new', EmployeeId, Pay
FROM inserted
;