Ervan uitgaande dat u een echte SQL Server MERGE
wilt
verklaring:
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);
Als u ook records in het doel wilt verwijderen die niet in de bron staan:
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;
Omdat dit een beetje populairder is geworden, heb ik het gevoel dat ik dit antwoord een beetje moet uitbreiden met enkele kanttekeningen om op te letten.
Ten eerste zijn er verschillende blogs die rapporteren over gelijktijdigheidsproblemen met de MERGE
verklaring
in oudere versies van SQL Server. Ik weet niet of dit probleem ooit is behandeld in latere edities. Hoe dan ook, dit kan grotendeels worden omzeild door de HOLDLOCK
. op te geven of SERIALIZABLE
vergrendel hint:
MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
[...]
U kunt hetzelfde bereiken met strengere transactie-isolatieniveaus.
Zoals het is, ook al heb ik nooit problemen gehad met de MERGE
statement zelf, ik gebruik altijd de WITH (HOLDLOCK)
hint nu, en ik gebruik de verklaring liever alleen in de meest eenvoudige gevallen.