更新语句检索不正确的值

时间:2018-06-20 18:58:56

标签: sql sql-server tsql sql-update subquery

我有以下两个表

PARTNERS

CREATE TABLE [dbo].[Partners](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[PartnerID] [varchar](50) NOT NULL,
[PartnerName] [nvarchar](200) NOT NULL,
[Active] [bit] NOT NULL,
[InactiveDate] [datetime] NULL,
[CreatedDate] [datetime] NOT NULL,
[RealmID] [int] NOT NULL

REALMS

CREATE TABLE [dbo].[Realms](
[RealmID] [int] NOT NULL,
[RapRealmID] [varchar](50) NOT NULL,
[RealmName] [varchar](50) NOT NULL,
[Description] [varchar](200) NULL,
[ApplicationID] [int] NOT NULL

当我运行以下正确构建的更新语句时,一切都会按预期工作-

UPDATE dbo.Partners 
SET RealmID = (Select RealmID From dbo.Realms WHERE RapRealmID = 'MyCompany')

但是,如果我错误地请求了Realms表中不存在的列 ID 而不是 RealmID ,则--

UPDATE dbo.Partners 
SET RealmID = (Select ID From dbo.Realms WHERE RapRealmID = 'MyCompany')

不会产生错误,并且可以通过从“合作伙伴”表中选择该记录的ID来更新“合作伙伴”表(即“合作伙伴”的表ID刚刚移至“ RealmID”字段)。

我知道在子查询中使用别名将克服此问题。但是,为什么SQL Server不会将子查询中的“选择”评估为必须成功执行的原子单元?单独运行Select ID From dbo.Realms WHERE RapRealmID = 'MyCompany'失败。为什么当它是子查询时会成功?

1 个答案:

答案 0 :(得分:2)

这与范围有关。 ID指向外部dbo.Partners表:

UPDATE dbo.Partners SET RealmID = (Select ID 
                                   From dbo.Realms 
                                   WHERE RapRealmID = 'MyCompany');
<=>
UPDATE dbo.Partners SET RealmID = (Select dbo.Partners.ID 
                                   From dbo.Realms 
                                   WHERE RapRealmID = 'MyCompany');

独立查询将错误:

Select ID From dbo.Realms WHERE RapRealmID = 'MyCompany';
-- there is no ID column

来自Subqueries

  

一般规则是,语句中的列名称由同一级别的FROM子句中引用的表隐式限定。 如果子查询的FROM子句中引用的表中不存在某列,则使用外部查询的FROM子句中的表对其进行隐式限定。 < / p>