2010-11-30 23 views
11

Microsoft SQL Server似乎在定義存儲過程時檢查列名有效性,但不檢查表名的有效性。如果它檢測到當前存在一個被引用的表名,它將在一個語句中驗證該表中的列名。因此,舉例來說,這將確定運行:爲什麼Microsoft SQL Server檢查存儲過程中的列而不是表?

CREATE PROCEDURE [dbo].[MyProcedure] 
AS 
BEGIN 
    SELECT 
     Col1, Col2, Col3 
    FROM 
     NonExistentTable 
END 
GO 

...如將這樣的:

CREATE PROCEDURE [dbo].[MyProcedure] 
AS 
BEGIN 
    SELECT 
     ExistentCol1, ExistentCol2, ExistentCol3 
    FROM 
     ExistentTable 
END 
GO 

...但是這將失敗,並「無效的列名稱:

CREATE PROCEDURE [dbo].[MyProcedure] 
AS 
BEGIN 
    SELECT 
     NonExistentCol1, NonExistentCol2, NonExistentCol3 
    FROM 
     ExistentTable 
END 
GO 

爲什麼SQL Server檢查列而不是表存在?當然,這是不一致的。它應該既做,也不做。對於我們來說,定義可能引用的表和/或列在架構中不存在的SP是很有用的,那麼是否有辦法關閉SQL Server在當前存在的表中存在列的檢查

回答

17

這稱爲延遲名稱解析。

有沒有辦法關閉它。你可以使用動態SQL或(一個討厭的黑客!)添加一個引用到一個不存在的表,以便延遲這個語句的編譯。

CREATE PROCEDURE [dbo].[MyProcedure] 
AS 
BEGIN 

CREATE TABLE #Dummy (c int) 

    SELECT 
     NonExistantCol1, NonExistantCol2, NonExistantCol3 
    FROM 
     ExistantTable 
    WHERE NOT EXISTS(SELECT * FROM #Dummy)  


DROP TABLE #Dummy 

END 
GO 
+0

哪是;不檢查表或檢查列? – Jez 2010-11-30 16:17:49

+0

表的非檢查。如果語句中使用的所有表都存在,則不會延遲。 – 2010-11-30 16:30:26

-2

這篇文章在MSDN應該回答你的問題。

從文章:

當第一次執行的存儲過程中,查詢 處理器讀取的存儲過程從 sys.sql_modules目錄視圖,並檢查的名稱文本過程使用的對象 存在。此過程稱爲延遲 名稱解析,因爲存儲的 過程所引用的表對象在創建存儲過程時不需要存在,但只有在執行時才存在 。

相關問題