Supondo que você queira um SQL Server
MERGE
real
declaração: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 você também deseja excluir registros no destino que não estão na origem:
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;
Como isso se tornou um pouco mais popular, sinto que devo expandir esta resposta um pouco com algumas ressalvas a serem observadas.
Primeiro, existem vários blogs que relatam problemas de simultaneidade com o
MERGE
declaração
em versões mais antigas do SQL Server. Não sei se esta questão já foi abordada em edições posteriores. De qualquer forma, isso pode ser amplamente contornado especificando o HOLDLOCK
ou SERIALIZABLE
dica de bloqueio:MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
[...]
Você também pode fazer a mesma coisa com níveis de isolamento de transação mais restritivos.
Existem vários outros problemas conhecidos com
MERGE
. (Observe que, como a Microsoft desativou o Connect e não vinculou problemas no sistema antigo a problemas no novo sistema, esses problemas mais antigos são difíceis de rastrear. Obrigado, Microsoft!) Pelo que posso dizer, a maioria deles não é comum problemas ou pode ser contornado com as mesmas dicas de bloqueio acima, mas não as testei. Como está, mesmo que eu nunca tenha tido problemas com o
MERGE
declaração, eu sempre uso o WITH (HOLDLOCK)
dica agora, e prefiro usar a declaração apenas nos casos mais diretos.