假设您想要一个实际的SQL Server MERGE 语句:
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);
如果您还想删除目标中不在源中的记录:
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;
因为这已经变得更受欢迎了,我觉得我应该稍微扩展一下这个答案,并注意一些注意事项。
首先,有几个博客在旧版本的 SQL Server 中报告了concurrency issues with the MERGE statement。我不知道这个问题是否在以后的版本中得到解决。无论哪种方式,这都可以通过指定HOLDLOCK 或SERIALIZABLE 锁定提示来解决:
MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
[...]
您也可以使用更严格的事务隔离级别来完成同样的事情。
有several other known issues 和MERGE。 (请注意,由于 Microsoft 核对 Connect 并且没有将旧系统中的问题与新系统中的问题联系起来,因此这些旧问题很难追查。谢谢,Microsoft!)据我所知,它们中的大多数并不常见问题或可以使用与上述相同的锁定提示来解决,但我没有测试它们。
事实上,尽管我自己从未对MERGE 语句有任何问题,但我现在总是使用WITH (HOLDLOCK) 提示,并且我更喜欢仅在最直接的情况下使用该语句。