sql server中有2个表,一个是s1,一个是s2,它们都只包含id和name,两个表中的数据是这样的:
id name
----------- --------------------
1 a
2 b
(2 row(s) affected)
id name
----------- --------------------
1 A
1 B
1 C
(3 row(s) affected)
更新语句是这样的:
update s1 set name = g.name from s1 d, s2 g
where d.id = g.id
运行update语句后,我检查s1表,结果如下:
id name
----------- --------------------
1 A
2 b
我对这个结果很困惑,有人可以告诉我为什么吗?在我看来,我认为这应该抛出异常,因为更新返回了多行
答案 0 :(得分:2)
我不确定“意外”是什么意思。两个表之间具有匹配条件,第二个表中的多个行匹配第一个表中的每一行。
SQL Server为更新选择任意匹配的行。在documentation:
中明确 解释了这一点指定FROM子句以提供条件时要小心 用于更新操作。 UPDATE语句的结果是 如果语句包含不是的FROM子句,则为undefined 以这样的方式指定,每个只有一个值可用 更新的列出现,即UPDATE语句是否 不确定。例如,在UPDATE语句中 在下面的脚本中,Table1中的两行都符合该资格 UPDATE语句中的FROM子句;但它未定义哪一行 来自Table1用于更新表2中的行。
此外,您应该使用显式JOIN
语法编写查询:
update s1
set name = g.name
from s1 d join
s2 g
on d.id = g.id;
在这种情况下,我不相信任何数据库都会出错。就底层引擎而言,确定一行是否多次更新有点棘手。
答案 1 :(得分:1)
结果是未定义的,因为连接为id = 1
生成3行,所有这些都是更新的候选者。 SQL Server不会像处理(比如说)子查询那样将多行视为错误,但是您可能希望避免这种行为。
答案 2 :(得分:0)
不,它不会抛出异常。会发生什么?
它会在s2中查找与1匹配的ID,并将它找到的第一个匹配ID设置为s1.name。
其余的是如此清楚,当它找不到2它没有改变任何东西;)