2013-04-28 43 views
0

在這裏,我將表明,從另一個函數引用不存在的功能,可以和SQL Server不檢查,直到執行時間:爲什麼我可以在另一個函數中引用一個不存在的函數?

USE [SomeDataBase]; 
SELECT dbo.Booo(); 

顯然,如果你不具備的功能Booo然後將無法識別功能Booo的錯誤。儘管這並不令人意外!

現在試試這個:

CREATE FUNCTION dbo.Foo() 
RETURNS INT 
AS 
BEGIN 
    DECLARE @Temp INT 
    SET @Temp = (SELECT dbo.Booo()) 
    RETURN 1 
END 

出人意料的是,這股代息儘管在Booo功能不會退出創建功能Foo

有什麼想法?

+5

這是標準的,記錄的SQL Server行爲。這是**功能** - 不是bug。 – 2013-04-28 07:59:47

+0

@marc_s:任何參考? – Alireza 2013-04-28 08:42:13

+5

請參閱[延遲名稱解析](http://msdn.microsoft.com/en-us/library/ms190686.aspx) - 這適用於函數和過程 – 2013-04-28 08:53:14

回答

4

你爲什麼認爲這是一個錯誤?由於代碼實際上不是執行,直到您運行Foo函數,有一個情況是是應該進行檢查的點。

也許你以自上而下的方式編寫自己的函數,而不是自下而上的方式,而且你希望先編寫上層,稍後再深入細節。

除非它的記錄工作的一種方式,它工作的另一種方式,它是不是一個錯誤,只是你得到你想要的,你和微軟之間的分歧:-)

+0

首先,我不認爲我們在應用程序生命週期中只能使用唯一的設計策略,有時我們有時會自上而下進行自上而下的設計。而且數據庫重構很重要。無論如何,我認爲marc_a的評論和引用非常有啓發性 – Alireza 2013-04-28 09:27:16

+2

@Alireza,我沒有說你應該只使用一種策略。事實上,必須存在的功能會限制你自下而上。如果你想使用自頂向下,你需要能夠創建引用不存在的項目(你還沒有定義)的東西。無論如何,它仍然只是一個_bug_,如果你可以找到說不允許的doco。 – paxdiablo 2013-04-28 09:54:22

+0

沒錯,現在我找到你了。謝謝 – Alireza 2017-07-14 06:54:04

2

如果你

CREATE FUNCTION dbo.Foo() 
RETURNS INT 
WITH SCHEMABINDING 
AS 
BEGIN 
    DECLARE @Temp INT 
    SET @Temp = (SELECT dbo.Booo()) 
    RETURN 1 
END 

錯誤並且該功能未被創建。這確實會改變未來更加痛苦的dbo.Booo的定義(然而,首先需要降低dbo.Foo)。

您還可以使用SQL Server Data Tools項目來驗證諸如不使用模式綁定而引用不存在的對象/列之類的東西。

相關問題