Forudsat at du ønsker en faktisk SQL-server MERGE
erklæring:
MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
USING dbo.temp_energydata AS source
ON target.webmeterID = source.webmeterID
AND target.DateTime = source.DateTime
WHEN MATCHED THEN
UPDATE SET target.kWh = source.kWh
WHEN NOT MATCHED BY TARGET THEN
INSERT (webmeterID, DateTime, kWh)
VALUES (source.webmeterID, source.DateTime, source.kWh);
Hvis du også vil slette poster i målet, der ikke er i kilden:
MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
USING dbo.temp_energydata AS source
ON target.webmeterID = source.webmeterID
AND target.DateTime = source.DateTime
WHEN MATCHED THEN
UPDATE SET target.kWh = source.kWh
WHEN NOT MATCHED BY TARGET THEN
INSERT (webmeterID, DateTime, kWh)
VALUES (source.webmeterID, source.DateTime, source.kWh)
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
Fordi dette er blevet lidt mere populært, føler jeg, at jeg bør udvide dette svar lidt med nogle forbehold, som jeg skal være opmærksom på.
For det første er der adskillige blogs, som rapporterer samtidighedsproblemer med MERGE
erklæring
i ældre versioner af SQL Server. Jeg ved ikke, om dette problem nogensinde er blevet behandlet i senere udgaver. Uanset hvad, kan dette stort set løses ved at angive HOLDLOCK
eller SERIALIZABLE
låsetip:
MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
[...]
Du kan også opnå det samme med mere restriktive transaktionsisoleringsniveauer.
Som det er, selvom jeg aldrig har haft problemer med MERGE
selv, bruger jeg altid WITH (HOLDLOCK)
tip nu, og jeg foretrækker kun at bruge udsagnet i de mest ligetil tilfælde.