我有一个表,数据名为energydata
它只有三列
(webmeterID, DateTime, kWh)
我有一个表中的一组新的数据更新temp_energydata
。
该DateTime
和webmeterID
保持不变。 但kWh
值需要从更新temp_energydata
表。
我怎样写的T-SQL这样做的正确方法是什么?
我有一个表,数据名为energydata
它只有三列
(webmeterID, DateTime, kWh)
我有一个表中的一组新的数据更新temp_energydata
。
该DateTime
和webmeterID
保持不变。 但kWh
值需要从更新temp_energydata
表。
我怎样写的T-SQL这样做的正确方法是什么?
假设你想要一个实际的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;
因为这已经变得有点更受欢迎,我觉得我应该扩大这个答案有一些需要注意的一点要注意的。
首先,有几个博客,其报告与并发问题MERGE
语句在旧版本的SQL Server。 我不知道这个问题曾经被在以后的版本解决。 无论哪种方式,这在很大程度上可以通过指定工作围绕HOLDLOCK
或SERIALIZABLE
锁提示:
MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
[...]
你也可以做到同样的事情更严格的事务隔离级别。
还有其他一些已知问题与MERGE
。 (请注意,由于微软核爆连接,并没有在旧系统中的问题,在新系统连接问题,这些老问题很难追查。谢谢,微软!)从我可以告诉,他们大多是不常见问题或可以用相同的锁定提示如上进行合作周围,但我没有测试过。
正因为如此,尽管我从来没有任何问题与MERGE
语句中的自己,我总是使用WITH (HOLDLOCK)
现在暗示,我更喜欢只在最简单的情况下使用的语句。
我经常用培根伟大的答案,我只是不能记住语法。
但我通常会添加一个CTE为除了使删除零件更有用,因为很多时候你会想合并仅适用于目标表的一部分。
WITH target as (
SELECT * FROM dbo.energydate WHERE DateTime > GETDATE()
)
MERGE INTO target WITH (HOLDLOCK)
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
如果你只需要在更新您的记录energydata
基于数据temp_energydata
,假设temp_enerydata
不包含任何新的记录,那么试试这个:
UPDATE e SET e.kWh = t.kWh
FROM energydata e INNER JOIN
temp_energydata t ON e.webmeterID = t.webmeterID AND
e.DateTime = t.DateTime
这里正在sqlfiddle
但是,如果temp_energydata
包含了新的记录,你需要插入它energydata
一个说法最好那么你一定要与培根给出了答案去。
UPDATE ed
SET ed.kWh = ted.kWh
FROM energydata ed
INNER JOIN temp_energydata ted ON ted.webmeterID = ed.webmeterID
Update energydata set energydata.kWh = temp.kWh
where energydata.webmeterID = (select webmeterID from temp_energydata as temp)
正确的做法是:
UPDATE test1
INNER JOIN test2 ON (test1.id = test2.id)
SET test1.data = test2.data