I think this works because determining whether a row in the source has a match in the target is done once at the start of the operation so that neither row has a match at that point.
>
Is that what is happening?
I don't see your tables or query, but this example illustrates:
CREATE TABLE #target(a int NOT NULL,
b int NOT NULL,
PRIMARY KEY (a,b))
CREATE TABLE #source(a int NOT NULL,
b int NOT NULL,
PRIMARY KEY (a,b))
INSERT #target (a, b) VALUES (1, 1)
INSERT #source (a, b) VALUES (2, 1), (2, 2)
go
MERGE #target t
USING #source s ON t.a = s.a
WHEN NOT MATCHED BY TARGET THEN
INSERT (a, b) VALUES(s.a, s.b)
WHEN MATCHED THEN
UPDATE
SET b = s.b
;
SELECT a, b FROM #target
As you see both rows from #source are inserted., since none of them are matching.
Observe now what happens if we re-run the MERGE statement:
Msg 8672, Level 16, State 1, Line 12
The MERGE statement attempted to UPDATE or DELETE the same row more than once. This happens when a target row matches more than one source row. A MERGE statement cannot UPDATE/DELETE the same row of the target table multiple times. Refine the ON clause to ensure a target row matches at most one source row, or use the GROUP BY clause to group the source rows.
This is different from an UPDATE where a value will be arbitrarily chosen from the source.
And it will break if I drop the surrogate PK and create one on the business key that is being used to do the match because it will end up with a duplicate. Is that also correct?
Again, I don't see your tables, so I'm uncertain what you have in mind. If you slap on a PK on the source table, you can not do that only on the columns you use in the MERGE, since, as I understand it, you have duplicate values for this key. If you add a PK on the full key on the source, but keep the MERGE statement, nothing is going to change. The example above illustrates.