2009-08-29 115 views
3

使用SQL Server 2005執行以下語句(我的測試是通過SSMS)導致第一次執行時成功並且在後續執行時失敗。選擇非失敗列失敗

IF OBJECT_ID('tempdb..#test') IS NULL 
    CREATE TABLE #test (GoodColumn INT) 
IF 1 = 0 
    SELECT BadColumn 
    FROM #test 

這意味着有些事情是比較我在我的select語句訪問對錶上存在的腳本「編譯」當列的列。爲我的目的,這是不受歡迎的功能。我的問題是,是否有任何可以完成的工作,以便在每次運行中都能成功執行此代碼,或者如果這是不可能的,也許有人可以解釋爲什麼演示功能是可取的。我目前唯一的解決方案是用EXEC或選擇*來包裝選擇,但我不喜歡那些解決方案。

感謝

回答

0

無論這種行爲是從一個程序員的角度是值得商榷的當然是「希望」 - 它基本上可以歸結爲靜態類型和動態類型語言之間的差異。從性能角度來看,這是可取的,因爲SQL Server需要完整的信息才能編譯和優化執行計劃(以及緩存執行計劃)。

總之,T-SQL是而不是是一種解釋型或動態類型的語言,因此您不能編寫這樣的代碼。您的選擇是使用EXEC,或者使用其他語言並在其中嵌入SQL查詢。

3

如果你把:

IF OBJECT_ID('tempdb..#test') IS NOT NULL 
    DROP TABLE #test 
GO 

比賽一開始,那麼這個問題就會迎刃而解,因爲#TEST表存在之前分批將得到解析。

你所要求的是讓系統認識到「1 = 0」總會被評估爲假。如果它是真的(對於大多數現實生活條件來說可能是這種情況),那麼你可能會想知道你將要運行一些會導致失敗的事情。

如果刪除臨時表,然後創建一個存儲過程,做同樣的:

CREATE PROC dbo.test 
AS 
BEGIN 
    IF OBJECT_ID('tempdb..#test') IS NULL 
    CREATE TABLE #test (GoodColumn INT) 

    IF 1 = 0 
    SELECT BadColumn 
    FROM #test 
END 

那麼這會很樂意被創建,並且只要你喜歡,你可以運行它多次。

羅布

+0

我在SQL嘗試這兩種解決方案都和失敗,「無效的列名稱BadColumn「。「 – 2009-08-29 06:30:40

+0

如果臨時對象不存在,那麼我可以創建這個dbo.test proc,並重復運行它。如果臨時對象存在,那麼你會得到錯誤。 – 2009-08-29 07:06:33

+0

+1爲好的解釋。表格表示無法找到BadCOlumn,「延遲名稱解析」適用於以後的使用。 – gbn 2009-08-29 08:32:17

0

這個問題也可見於下列情形:

IF 1 = 1 
    select dummy = GETDATE() into #tmp 
ELSE 
    select dummy = GETDATE() into #tmp 

雖然第二條語句永遠不會執行發生同樣的錯誤。 似乎查詢引擎第一級驗證忽略所有條件語句

0

你說你有後續請求的問題,那是因爲對象已經退出。它建議您在完成後儘快放下臨時表。

在閱讀更多關於臨時表的性能: SQL Server performance.com