Код в вашем примере работает, вот пример, который легко воспроизвести
;with cteT as ( SELECT * FROM (VALUES (1,'T1 Val 1') , (2,'T1 Val 2') , (4,'T1 Val 4') ) as T1(ID, Curve)
)SELECT * INTO #Dest FROM cteT
;with cteT as ( SELECT * FROM (VALUES (3,'T2 Val 3') , (4,'T2 Val 4') , (5,'T2 Val 5') ) as T1(ID, Curve)
)SELECT * INTO #Srce FROM cteT;
MERGE INTO #Dest as T1
USING #Srce as T2 ON T1.ID=T2.ID
WHEN MATCHED THEN UPDATE SET T1.Curve=T2.CURVE
WHEN NOT MATCHED BY TARGET
THEN INSERT (ID, Curve) VALUES(T2.ID, T2.Curve)
;
SELECT * FROM #Dest ORDER BY ID
DROP TABLE #Dest
DROP TABLE #Srce
Это вывод, обратите внимание, что для 1 и 2 значение не изменяется, для 4 оно обновляется с T2, а для 3 и 5 он вставлен из T2.
ID Curve
1 T1 Val 1
2 T1 Val 2
3 T2 Val 3
4 T2 Val 4
5 T2 Val 5
Это означает, что, скорее всего, проблема либо в ваших значениях для T2.ID, либо ваш образец слишком урезан и пропускает сложность в вашем реальном коде. Я бы начал с проверки ваших данных в T2.ID
SELECT ID, COUNT(ID) as IDCount FROM DBO.Table2 GROUP BY ID HAVING COUNT(*) > 1
SELECT * FROM DBO.Table2 WHERE ID IS NULL
и посмотрел, появляются ли какие-либо записи. Если оба они пусты, посмотрите на ваш реальный код слияния и посмотрите, как он может отличаться от того, что вы опубликовали. Если вы разместите обновленный пример кода, я постараюсь посмотреть.