SQL 临时表不应该抛出无效的列名错误

lit*_*ris 3 t-sql sql-server-2008

我在 SQL Server 2008 Management Studio 中发现了以下问题。当我整体运行以下脚本时,我预计会出现错误(由于“复制和粘贴错误”),但不会收到它们。

IF OBJECT_ID('Foo') IS NOT NULL
BEGIN
    DROP TABLE Foo
END
IF OBJECT_ID('Bar') IS NOT NULL
BEGIN
    DROP TABLE Bar
END
CREATE TABLE Foo (
    FooID int
)
Create Table Bar (
    BarID int
,   FooID int
)
INSERT INTO Foo
SELECT 1 UNION ALL SELECT 2
INSERT INTO Bar
SELECT 1,1 UNION ALL SELECT 2,1 UNION ALL SELECT 3,1
GO

IF OBJECT_ID('tempdb..#temp') IS NOT NULL
BEGIN
      DROP TABLE #TEMP
END
GO
CREATE TABLE #TEMP (
    FooID int
)
INSERT INTO #TEMP
    SELECT FooID FROM Bar
GO
SELECT * FROM Foo WHERE FooID IN (SELECT FooID FROM #TEMP)
GO
SELECT * FROM Bar WHERE BarID IN (SELECT BarID FROM #TEMP)
GO
SELECT * FROM #TEMP
GO
Run Code Online (Sandbox Code Playgroud)

包含“SELECT BarID FROM #TEMP”上的 where 子句过滤器的倒数第二条语句运行,但 #TEMP 中没有 BarID 列。将脚本作为一个整体运行时,我没有收到任何错误,脚本返回 Foo 中的所有行。但是,当我单独运行该命令时,我收到错误消息,通知我 #TEMP 中没有 BarId。

是否有一个原因?是我的代码吗?

Nei*_*oss 5

您的倒数第二个查询实际上工作正常。

其他评论者请纠正我,但我理解这是一个相关的子查询。表别名将显示实际发生的情况。您的查询相当于:

SELECT * FROM Bar x WHERE x.BarID IN (SELECT x.BarID FROM #TEMP)
Run Code Online (Sandbox Code Playgroud)

对于#TEMP 中的每一行,嵌套的select 实际上是从表Bar 中返回BarID 的当前值,所以是的,(BarID) 中的BarID 为true,因此Bar 中的每一行都匹配,因此返回每一行。

为了表明你不是疯子,试试

SELECT * FROM Bar WHERE BarID IN (SELECT NonExistentFieldName FROM #TEMP) 
Run Code Online (Sandbox Code Playgroud)

这引发了我认为您期望的错误。