What happens when your MERGE statement INSERTs a row that now satisfies the ON constraint. If a new row comes along that satisfies the ON constraint will it fall into WHEN MATCHED or WHEN NOT MATCHED?
Let's use an example piece of code to decide what happens. Here I have two table variables created and seeded with some random data:
DECLARE @t1 Table (id int, name varchar(12)) INSERT INTO @t1 VALUES(1, 'hi') DECLARE @t2 Table (id int, name varchar(12)) INSERT INTO @t2 VALUES(1, 'bye') INSERT INTO @t2 VALUES(3, 'colin') INSERT INTO @t2 VALUES(3, 'sarah')
Now I will attempt to MERGE @t2 into @t1. If you have not come across MERGE before it is basically a more efficient way of saying UPDATE if it exists or INSERT if it is new.
MERGE @t1 AS t1 USING(SELECT * FROM @t2) AS t2 ON t2.id = t1.id WHEN MATCHED THEN UPDATE SET t1.name = t2.name WHEN NOT MATCHED THEN INSERT(id, name) VALUES(t2.id, t2.name);
So, what we are saying is:
- USING this source of data (SELECT * FROM @t2)
- ON this decider (matching the ID's to judge if this row already exists)
- WHEN the ON clause is MATCHED update this row with new values
- WHEN NOT MATCHED we should INSERT the new row
But, given the values in @t2, what will happen?
- The 1st row will match on ID 1 and so will do an UPDATE
- The 2nd row doesn't have a match for an ID of 3 so will INSERT
- The 3rd row didn't have a match for an ID of 3 before but since the last INSERT it now does. So INSERT or UPDATE?
SELECT * FROM @t1 will show you that it has INSERTed twice...
So watch out for this. The constraint is decided about the source and destination once at the beginning and not again so you should be sure that the source table being MERGED is complete in itself. You can do with using a GROUP BY or DISTINCT on the USING table. Whichever is most appropriate for your scenario.