sql >> Databáze >  >> RDS >> Sqlserver

SQL příkaz MERGE pro aktualizaci dat

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.



  1. Konstrukce SQL dotazu - rozdělení dat ve sloupci do dvou sloupců

  2. Víceúrovňová smyčka for v PHP

  3. Jak vytvořit nového uživatele a udělit oprávnění v MySQL

  4. Jak se dva níže uvedené aktualizační příkazy liší v SQL?