我有一个有效的MySQL查询,它为给定用户更新或插入数据(多行),与默认用户' admin'相同。它适用于MySQL,但我很难将其转换为Microsoft SQL Server 2012等效版本。
MySQL查询是:
REPLACE INTO table_name (user, name, sub_name, display, html_div, display_order, good_low, good_high, critical_low, warning_low, warning_high, critical_high, last_updated)
SELECT 'user1', name, sub_name, display, html_div, display_order, good_low, good_high, critical_low, warning_low, warning_high, critical_high, last_updated
FROM table_name WHERE user = 'admin'
我尝试将其转换为SQL Server的是:
MERGE table_name AS TARGET
USING (SELECT 'user1', name, sub_name, display, html_div, display_order, good_low, good_high, critical_low, warning_low, warning_high, critical_high, last_updated FROM table_name WHERE [user] = 'admin')
AS SOURCE ([user], name, sub_name, display, html_div, display_order, good_low, good_high, critical_low, warning_low, warning_high, critical_high, last_updated)
ON TARGET.[user] = 'admin'
WHEN MATCHED THEN
UPDATE
SET [user] = 'user1', name = SOURCE.name, sub_name = SOURCE.sub_name, display = SOURCE.display, html_div = SOURCE.html_div, display_order = SOURCE.display_order, good_low = SOURCE.good_low, good_high = SOURCE.good_high, critical_low = SOURCE.critical_low, warning_low = SOURCE.warning_low, warning_high = SOURCE.warning_high, critical_high = SOURCE.critical_high, last_updated = SOURCE.last_updated
WHEN NOT MATCHED THEN
INSERT ([user], name, sub_name, display, html_div, display_order, good_low, good_high, critical_low, warning_low, warning_high, critical_high, last_updated)
VALUES ('user1', SOURCE.name, SOURCE.sub_name, SOURCE.display, SOURCE.html_div, SOURCE.display_order, SOURCE.good_low, SOURCE.good_high, SOURCE.critical_low, SOURCE.warning_low, SOURCE.warning_high, SOURCE.critical_high, SOURCE.last_updated);
我收到错误:
Msg 8672, Level 16, State 1, Line 1
The MERGE statement attempted to UPDATE or DELETE the same row more than once. This happens when a target row matches more than one source row. A MERGE statement cannot UPDATE/DELETE the same row of the target table multiple times. Refine the ON clause to ensure a target row matches at most one source row, or use the GROUP BY clause to group the source rows.
但是查询预计会更新多行,所以我想我需要一些不同的东西。
你能帮我把这个MySQL查询转换成它的等效SQL Server吗?
答案 0 :(得分:1)
MERGE要求源行上的唯一值与目标中的行匹配。否则它不知道要使用哪一个源行 - 它们可能不同!在这种情况下,您尚未指定从TARGET到SOURCE的任何匹配。 ON TARGET.[user] = 'admin'
应该是ON TARGET.[user] = SOURCE.[user]
。每个源行应匹配一个(或多个目标行)。但是每个目标行应该只匹配一个源行。
因此,您在SOURCE中创建“相似”行,然后将用户ID与目标表进行比较。如果用户已经在那里,则重写数据以使其看起来相似。否则插入一个新行。