One of my favourite features of SQL Server 2008 is the Merge or 'upsert' Statement. Lets say we have an ETL process that prepares a data stage table, without the merge statement you might first delete all the records from the staging table and then insert them all again. If you have large data sets this can become quite time consuming and well frankly it doesn't seem very elegant. Another alternative is to use a cursor to iterate over each record and look for changes, you might also have data that has a timestamp which might help you write a set based operation, both of these approaches are less than ideal.
Well as of SQL 2008 you can use the Merge Statement:
Lets say you have a simple table like:
CREATE TABLE People
(
ID INT PRIMARY KEY,
Name Varchar(50) NOT NULL,
Position Varchar(50) NOT NULL,
Age INT NOT NULL
);
Assuming our StagedPeople table is the same structure the merge statement would look like:
MERGE INTO People
USING StagedPeople
ON People.ID = StagedPeople.ID
WHEN MATCHED THEN
-- if we find a match, then perform an update
UPDATE SET
Age = StagedPeople.Age,
Name = StagedPeople.Name,
Position = StagedPeople.Position
WHEN NOT MATCHED THEN
-- if we don't find a match, then insert a new record
INSERT (ID, Name, Position, Age)
VALUES (StagedPeople.keycol, StagedPeople.Name, StagedPeople.Position, StagedPeople.Age)
WHEN SOURCE NOT MATCHED THEN
-- we could delete the record, since it's not found in the Staged table
DELETE;
OUTPUT $Action
The $action variable returns a varchar(20) of the operation that has taken place, i.e. 'INSERT', 'UPDATE', 'DELETE'
The operations and full reference can be found here.
It seems like a pretty fundamental operation, glad it only took till 2008 for us to have it :)