2011-08-15 30 views
2

我在SQL Server 2008 Management Studio中發現了以下問題。當我整體運行下面的腳本時,我期望錯誤(由於「複製和粘貼錯誤」),但不會收到它們。SQL臨時表不會拋出無效的列名稱應該發生錯誤

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 

含有「選擇BarID FROM #TEMP」 where子句過濾器的倒數第二個語句運行,但在#TEMP沒有BarID列。當作爲一個整體運行腳本時,我不會收到任何錯誤,腳本將返回Foo中的所有行。但是,當我自己運行該命令時,我收到錯誤通知我#TEMP中沒有BarId。

這是有原因嗎?它是我的代碼嗎?

+1

如果您知道BarID不在#TEMP中,您爲什麼要從#TEMP中選擇BarID? – Paparazzi

+0

正如它在我的問題中說的那是我的錯誤 - 問題不在於我的代碼有多有效,但爲什麼錯誤不會拋出....這是由尼爾 – littlechris

回答

4

您的第二個到最後一個查詢實際上工作正常。

其他評論請糾正我,但我明白這是一個相關的子查詢。表格別名將顯示實際發生的情況。您的查詢是相同的:

SELECT * FROM Bar x WHERE x.BarID IN (SELECT x.BarID FROM #TEMP) 

對於#TEMP每一行,嵌套的選擇實際上是從表返回酒吧的BarID的電流值,所以是的,在BarID(BarID)是真實的,所以每行在酒吧是匹配的,所以每一行都會返回。

爲了證明你是不是瘋了,嘗試

SELECT * FROM Bar WHERE BarID IN (SELECT NonExistentFieldName FROM #TEMP) 

這就提出了一個錯誤,我認爲你期待。

+0

回答謝謝尼爾 - 這是一個意外的相關子查詢..需要使用完整的命名,或至少表別名! – littlechris

+0

+1這在'DELETE'情況下特別危險,因爲它會導致你不小心清除整個桌子。 –

+0

絕對 - 這就是爲什麼所有的代碼都經歷了開發/測試/實況升級:) – littlechris

0

有關Neil的回答一些背景知識,請參見下面的知識庫文章:

http://support.microsoft.com/kb/298674

他們使用(的作品雖然看來,它不應該)是非常相似的例子(這個例子雖然沒有#TEMP表):

CREATE TABLE X1 (ColA INT, ColB INT) 
CREATE TABLE X2 (ColC INT, ColD INT) 
SELECT ColA FROM X1 WHERE ColA IN (Select ColB FROM X2) 

他們還表明,添加表的別名(這是有很多原因一個很好的做法,但將避免此問題得到過去編譯)使得查詢失敗,因爲您最初ê xpected。

這實際上是繼列分辨率的ANSI標準,並不會改變(除非它們實現厄蘭的SET STRICT_CHECKS ON)。

誰抱怨這個錯誤(和更多的背景,爲什麼發動機有這樣的工作方式)有些人:

http://connect.microsoft.com/SQL/feedback/details/542289/

http://connect.microsoft.com/SQL/feedback/details/422252/

http://connect.microsoft.com/SQL/feedback/details/126785/

不得不同意@ BalamBalam的評論:你爲什麼寫了無效的代碼,然後抱怨說它被誤認爲是有效的?

+0

我很感謝你的詳細答案,但是我所問的原因是因爲我最初的想法是代碼應該拋出錯誤而不是運行 - 因此我的問題標題......不太確定「抱怨」在我的問題中。 – littlechris

相關問題