Home | Blog | Screencasts | Projects
# Monday, September 08, 2008

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 :)

Monday, September 08, 2008 11:01:17 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0] - Trackback
code | SQL Server | Work
Statistics
Total Posts: 134
This Year: 0
This Month: 0
This Week: 0
Comments: 20