2011-11-22 41 views
4

爲什麼MS Sql Server(2005和2008;未經測試其他地方)如果某個列在表上不存在時會引發錯誤,然後在表不存在時引發錯誤?爲什麼MS Sql Server在表中不存在列時不會出現錯誤,如果表不存在?

更具體地說,我有以下模式(高度降低,以顯示一切重要):

CREATE TABLE table1 (
id int identity(1,1) primary key 
) 

爲什麼下面的查詢失敗,錯誤Invalid column name 'iDoNotExist'.

if 1=2 
begin 
    print 'table that shouldn''t exist does' 
    select * from [IDoNotExist] 
end 

if 1=2 
begin 
    print 'column that shouldn''t exist does' 
    select iDoNotExist from table1 
end 

我希望它會無法多個錯誤(因爲它會如果它實際上編譯,發現表和列都沒有了),或者沒有錯誤(因爲它會如果它忽略了,如果內容因爲他們不會運行)。我能做些什麼來讓它無誤地運行?

PS實際的查詢有這樣的if語句,但它並沒有任何區別:

exists (select * from [INFORMATION_SCHEMA].[COLUMNS] t where t.[TABLE_NAME] = 'table1' and t.[COLUMN_NAME] = 'iDoNotExist') 
+1

你確定'兩個SQL塊'的if'= 2'存在嗎? – Oded

+0

在Sql Server 2008 Express Edition上,我可以創建該模式,然後運行該查詢並獲得該錯誤;如果我註釋掉選擇列的行,我會得到我想要的輸出。 –

回答

7

你看到的deferred name resolution對錶的影響。

+0

+1非常有趣的閱讀,喬。 – 2011-11-22 22:13:31

+0

謝謝,我能做些什麼嗎? –

2

RE:

我能做些什麼來得到它的無差錯運行?

使用EXEC以便該語句運行在未編譯的子批處理中,除非採用IF分支。

IF 1 = 2 
    BEGIN 
     PRINT 'column that shouldn''t exist does' 

     EXEC ('SELECT iDoNotExist FROM table1') 
    END 

另外一個理論上的可能性是通過在無操作參考另一個不存在的表上添加推遲違規語句的編譯。

IF 1 = 2 
    BEGIN 
     PRINT 'column that shouldn''t exist does' 

     CREATE TABLE #T(X INT) 

     SELECT iDoNotExist 
     FROM table1, (SELECT MAX(X) X FROM #T) T 

     DROP TABLE #T 
    END 

無法想象任何情況下,將優先於EXEC有用。

相關問題