Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Instruction SQL MERGE pour mettre à jour les données

En supposant que vous vouliez un réel SQL Server MERGE déclaration :

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

Si vous souhaitez également supprimer des enregistrements dans la cible qui ne sont pas dans la source :

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;

Parce que cela est devenu un peu plus populaire, je pense que je devrais développer un peu cette réponse avec quelques mises en garde à prendre en compte.

Tout d'abord, plusieurs blogs rapportent problèmes de concurrence avec le MERGE déclaration dans les anciennes versions de SQL Server. Je ne sais pas si ce problème a déjà été abordé dans les éditions ultérieures. Dans tous les cas, cela peut être largement contourné en spécifiant le HOLDLOCK ou SERIALIZABLE indice de verrouillage :

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

Vous pouvez également accomplir la même chose avec des niveaux d'isolement des transactions plus restrictifs.

Il existe plusieurs autres problèmes connus avec MERGE . (Notez que depuis que Microsoft a supprimé Connect et n'a pas lié les problèmes de l'ancien système aux problèmes du nouveau système, ces problèmes plus anciens sont difficiles à localiser. Merci, Microsoft !) D'après ce que je peux dire, la plupart d'entre eux ne sont pas courants problèmes ou peuvent être contournés avec les mêmes conseils de verrouillage que ci-dessus, mais je ne les ai pas testés.

En l'état, même si je n'ai jamais eu de problèmes avec le MERGE déclaration moi-même, j'utilise toujours le WITH (HOLDLOCK) indice maintenant, et je préfère n'utiliser l'instruction que dans les cas les plus simples.