質問

I am trying to merge two tables using SQL Merge, in the below script:

 BEGIN TRAN;
DECLARE @T TABLE(Id BigInt);
MERGE Target AS T
USING Source AS S
ON (T.ObjectName = S.ObjectName) 
WHEN NOT MATCHED BY TARGET 
     THEN INSERT(ObjectName,Value,[TimeStamp],Quality) VALUES(S.ObjectName, S.Value,S.[TimeStamp],S.Quality)
WHEN MATCHED 
    THEN UPDATE SET 
    T.Value = S.Value,
    T.Quality=S.Quality

OUTPUT S.Id INTO @T;
DELETE Source
WHERE Id in (SELECT Id
                     FROM @T);
if @@Error > 0
Rollback
else
COMMIT Tran
GO 

What I am trying to do is to insert new records from "Target" to "Source", and the "Matched" records will be updated in the "Source" Table. The issue I am facing is that sometimes, the source table has two identical "Not Matched Rows". According to the script logic and to my requirement, it should insert the first "Not Matched", then the second "Not Matched" will need to be treated as an update, not as an insert, since it is now a "Matched" row, because we have already inserted the first record.

It seems that my merge is working as one bulk script, where the first insert is not noticed when the script reaches to the second identical row. Is this how "SQL Merge" works or is it form my script?

Thanks

役に立ちましたか?

解決

Assuming the row with the later timestamp should "win", why not eliminate the duplicate as part of your SOURCE query:

;With Selection as (
    select ObjectName,Value,Quality,
      ROW_NUMBER() OVER (PARTITION BY ObjectName ORDER BY Timestamp desc) as rn,
      MIN(Timestamp) OVER (PARTITION BY ObjectName) as Timestamp
    from
      Source
)
MERGE Target AS T
USING (select * from Selection where rn=1) AS S
--The rest is unaltered
...

And this is not something unusual about MERGE - all DML statements act "as if" all rows are processed simultaneously.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top