Za předpokladu, že chcete skutečný SQL Server MERGE
prohlášení:
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);
Pokud chcete také odstranit záznamy v cíli, které nejsou ve zdroji:
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;
Protože se to stalo o něco populárnějším, mám pocit, že bych měl tuto odpověď trochu rozšířit s některými upozorněními.
Za prvé, existuje několik blogů, které hlásí problémy se souběhem s MERGE
prohlášení
ve starších verzích SQL Serveru. Nevím, zda byl tento problém někdy řešen v pozdějších vydáních. V každém případě to lze z velké části obejít zadáním HOLDLOCK
nebo SERIALIZABLE
nápověda k zámku:
MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
[...]
Můžete také dosáhnout stejné věci s přísnějšími úrovněmi izolace transakcí.
Existuje několik dalších známých problémů s MERGE
. (Všimněte si, že od té doby, co Microsoft nuked Connect a nepropojil problémy ve starém systému s problémy v novém systému, je těžké tyto starší problémy vystopovat. Díky, Microsoft!) Z toho, co mohu říci, většina z nich není běžná problémy nebo je lze obejít pomocí stejných zamykacích rad jako výše, ale netestoval jsem je.
Jak to je, i když jsem nikdy neměl žádné problémy s MERGE
sám, vždy používám WITH (HOLDLOCK)
nápověda nyní a dávám přednost použití příkazu pouze v těch nejpřímějších případech.