1

我想警告人们在使用 SQL IN 语句作为 WHERE 子句的一部分时遇到的问题(幸运的是在测试环境中而不是 LIVE 环境中)。

我构建了一个名为 [dataimport].[IDsToUpdate] 的临时表,其中包含我想使用以下 UPDATE 语句更新的 42 个 GUID 的列表:

UPDATE dbo.IndividualSponsors
SET LeaveDate = null
WHERE IndividualSponsorID in (select IndividualSponsorID from [dataimport].[IDsToUpdate])

[dataimport].[IDsToUpdate]表包含一个名为 IndvSponsorID 的 GUID 列。请注意我的 UPDATE 语句中的错误。它应该是:

select IndvSponsorID from [dataimport].IDsToUpdate

如果我select IndividualSponsorID from [dataimport].IDsToUpdate自己运行,它会错误地说该列IndividualSponsorID是未知的(如预期的那样)。

但是当我在上面的 UPDATE 语句中运行它时,它更新了我dbo.IndividualSponsors表中的所有 148,000 条记录(arrrrhhh !!!)。

我相信这是因为列名IndividualSponsorID存在于表 dbo.IndividualSponsors 中,并且当在 UPDATE 语句的完整上下文中运行时,SQL Server 将列引用重新指向该表,因此对所有行进行全面更新。

这对我来说似乎很错误,尤其是当我明确指出该列IndividualSponsorID是 FROM the table 时[dataimport].IDsToUpdate。它应该有错误,因为我的 IN SELECT 语句不正确。

士气:在进行更新时总是使用表别名(尤其是实时数据!):

例如select ids.IndividualSponsorID from [dataimport].IDsToUpdate ids

这如预期的那样失败。

有人对此有不同的看法吗?

4

1 回答 1

2

我同意评论者的观点。不幸的是,您有一个导致错误更新的错字,但 SQL 正在做正确的事情。想象一下它没有让你使用IndividualSponsorID,你想写一个这样的内部选择:

(select IndvSponsorID + IndividualSponsorID from [dataimport].[IDsToUpdate])

一列来自内部选择中引用的表,另一列来自外部更新中的表。有一些非常好的场景,你可能需要这样的东西。

这里真正的教训是在事务中运行您的手动更新,这样如果您发现受影响的行数与您的预期不符,您可以轻松地回滚它。

于 2013-10-25T10:31:56.430 回答