SQL Update语句未按预期运行

时间:2016-10-15 09:01:27

标签: sql sql-server

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

我对这个结果很困惑,有人可以告诉我为什么吗?在我看来,我认为这应该抛出异常,因为更新返回了多行

3 个答案:

答案 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它没有改变任何东西;)