相关的子查询应该抛出异常

时间:2012-05-15 00:24:43

标签: sql-server

抱歉标题不好 - 我想不出更好的标题。

基本上,SQL Server 2008正在处理我希望失败的子查询。

这是一个简单的例子:

CREATE TABLE UserDemographics
(
    UserID      INT,
    UserName    NVARCHAR(500)
)

CREATE TABLE UserAddresses
(
    UserAddressID   INT,
    Address     NVARCHAR(500)
)


INSERT INTO UserDemographics(UserID, UserName) VALUES(1, 'Joe'), (2, 'Sam'), (3, 'Ed')

INSERT INTO UserAddresses(UserAddressID, Address) VALUES(1, '1st Street'), (2, 'Old Address 1'), (3, 'Old Address 2')

DELETE FROM UserDemographics
WHERE UserID IN
(
    SELECT UserID FROM UserAddresses
)

以下是有趣的原因:UserAddresses没有名为UserID的列。相关子查询正在选择它正在查询的表中不存在的列。

显然,它与相关子查询有关 - UserIDUserDemographics表中的一列,由于某种原因,数据库正在进行该引用。

也许UserDemographics表隐含在子查询的from-list中。

任何人都能解释一下吗?

2 个答案:

答案 0 :(得分:6)

是。相关子查询采用UserDemographics.Userid,因为这是范围内唯一的UserId。

想象一下,你在人口统计表中有了AddressId并且做了:

DELETE FROM UserDemographics
WHERE AddressID IN ( SELECT AddressId FROM UserAddresses )

在这种情况下,子查询中的AddressId将来自UserAddresses。

这个故事的寓意是: 在引用子查询中的列时始终使用表名或别名。 以下内容会出现您所期望的错误:

DELETE FROM UserDemographics
WHERE UserID IN ( SELECT ua.UserId FROM UserAddresses ua)

答案 1 :(得分:0)

表UserAddresses的UserAddressID实际上是tableUserDemographics的UserID的外键

因为您提供的值

所以你应该使用UserAddressID

DELETE FROM UserDemographics
WHERE UserID IN
(
    SELECT UserAddressID FROM UserAddresses
)

但我的意思是此脚本将删除所有在UserAddresses表中具有地址的用户

在这种情况下,您应该添加where子句

DELETE FROM UserDemographics
WHERE UserID IN
(
    SELECT UserAddressID FROM UserAddresses where ???
)

除非您打算删除在UserAddresses表中具有引用的任何用户