Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Istruzione SQL MERGE per aggiornare i dati

Supponendo che tu voglia un effettivo SQL Server MERGE dichiarazione:

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);

Se desideri eliminare anche i record nella destinazione che non sono nell'origine:

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;

Poiché questo è diventato un po' più popolare, sento di dover ampliare un po' questa risposta con alcuni avvertimenti di cui essere a conoscenza.

Innanzitutto, ci sono diversi blog che riportano problemi di concorrenza con MERGE dichiarazione nelle versioni precedenti di SQL Server. Non so se questo problema sia mai stato affrontato nelle edizioni successive. Ad ogni modo, questo può essere ampiamente aggirato specificando il HOLDLOCK o SERIALIZABLE suggerimento per il blocco:

MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
[...]

Puoi ottenere lo stesso risultato anche con livelli di isolamento delle transazioni più restrittivi.

Esistono molti altri problemi noti con MERGE . (Si noti che poiché Microsoft ha bombardato Connect e non ha collegato i problemi nel vecchio sistema ai problemi nel nuovo sistema, questi vecchi problemi sono difficili da rintracciare. Grazie, Microsoft!) Da quello che posso dire, la maggior parte di essi non è comune problemi o può essere risolto con gli stessi suggerimenti di blocco di cui sopra, ma non li ho testati.

Così com'è, anche se non ho mai avuto problemi con MERGE io stesso, utilizzo sempre il WITH (HOLDLOCK) suggerimento ora, e preferisco usare l'affermazione solo nei casi più semplici.