什么原因会导致“受影响的行数”不正确?

8
使用 Microsoft SQL Server Management Studio 2008。我已经完成了一个简单的事务:
BEGIN TRAN

SELECT ko.ID, os.ID AS ID2
FROM table_a AS ko
JOIN table_b AS os ON os.ID=ko.ID
WHERE (ko.the_date IS NOT NULL AND os.the_date IS NULL);

UPDATE table_b SET the_date=ko.the_date
FROM table_a AS ko
JOIN table_b AS os ON os.ID=ko.ID
WHERE (ko.the_date IS NOT NULL AND os.the_date IS NULL);

SELECT ko.ID, os.ID AS ID2
FROM table_a AS ko
JOIN table_b AS os ON os.ID=ko.ID
WHERE (ko.the_date IS NOT NULL AND os.the_date IS NULL);


ROLLBACK

所以SELECT和UPDATE应该是相同的。并且结果应该返回0行。但是UPDATE影响的行比SELECT从数据库获取的行少:

(61 行受影响)

(60 行受影响)

(0 行受影响)

我在这里缺少什么?


1
表a有两行具有相同的id吗? - Arvo
1
这两个表中的ID字段是唯一的吗? - Beth
2个回答

2

我猜测最有可能的原因是,你的示例中Table_a表中有一行具有重复的ID - 这会导致第一个select中出现额外的一行连接,但是update仅处理Table_b表中的行,因此你的重复行并不重要。这个语句应该能帮你找到罪魁祸首:

SELECT ko.ID
FROM table_a AS ko
JOIN table_b AS os ON os.ID=ko.ID
WHERE (ko.the_date IS NOT NULL AND os.the_date IS NULL)
GROUP BY ko.ID
HAVING COUNT(*) > 1

是table_a具有table_b的重复外键,我无法找到它们,导致内部连接选择了2行,但更新只影响了table_b中的一行。我非常确定这是不允许的,但猜测在2004年有人认为这将是一个好主意!谢谢答案。 - Indrek

0

UPDATE...FROM 无法检测到此类歧义:

CREATE TABLE dbo.source
    (
      id INT NOT NULL ,
      SomeNumber INT
    )
GO
CREATE TABLE dbo.target
    (
      id INT NOT NULL
             PRIMARY KEY ,
      SomeNumber INT
    )
GO
INSERT  INTO dbo.source
        ( id, SomeNumber )
        SELECT  1 ,
                2
        UNION ALL
        SELECT  1 ,
                3

INSERT  INTO dbo.target
        ( id, SomeNumber )
        SELECT  1 ,
                0

UPDATE  dbo.TARGET
SET     SomeNumber = s.SomeNumber
FROM    dbo.source AS s
        JOIN dbo.TARGET AS t ON s.id = t.id

你的目标表中有两个匹配项在源表中,我们无法预先知道哪个值最终会更新目标表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接