Sql-Server

TSQL - 由使用者定義函式 (UDF) 返回並在內聯表值函式 (iTVF) 中使用的中間結果

  • June 28, 2017

我最近遇到了這個問題,想知道我的理解是否正確。我的 DNA 是後端開發人員(不是 DBA),但經常與 SQL 互動。我創建了兩個相同的函式(從結果數據的角度來看),並將它們按創建腳本的順序排列:

CREATE FUNCTION dbo.get_names_udf (@user_id nvarchar(24))
RETURNS NVARCHAR(500) 
AS
BEGIN
DECLARE
RETURN SELECT dbo.usernames(@user_id))
END
GO

CREATE FUNCTION dbo.get_names_itvf (@user_id nvarchar(24))
RETURNS TABLE 
AS
RETURN
(SELECT name = SELECT dbo.usernames(@user_id))
GO

-- dbo.usernames is a simple scalar function which is defined after both the functions above    

這就是我為我的數據庫創建所有函式的方式:

  1. 我從sysobjects
  2. 我再次重新創建所有功能。
  3. “該usernames()功能是在上述兩者之後創建的”。

當我嘗試執行所有函式創建腳本時 - 似乎我的 iTVF 創建失敗,因為它報告該usernames()函式不存在(這是預期的,因為對像被刪除,如上所述)。

Msg 4121, Level 16, State 1, Server XXXXXXXXX, Procedure get_names_itvf, Line 5
Cannot find either column "dbo" or the user-defined function or aggregate "dbo.usernames", or the name is ambiguous.

但對於 UDF 函式,它不會遇到此錯誤。

這是因為內聯 TVF 如何看到內部結果?或者是如何解決 UDF 和 iTVF 的依賴關係?

我不確定為什麼會發生這種情況,因此最好獲得一些指導/建議。

韓國,

當你創建一個標量函式時,你定義了返回類型

CREATE FUNCTION dbo.get_names_udf (@user_id nvarchar(24))
RETURNS NVARCHAR(500) 
AS
BEGIN
RETURN (SELECT dbo.usernames(@user_id))
END
GO

在這種情況下是 NVARCHAR(500),只要知道返回類型,SQL 伺服器就不需要檢查引用函式/表的底層結構。

如果使用者名函式(在這種情況下)將返回 NVARCHAR(500) 以外的其他內容,則它將無法執行,這是預期的

另一方面

CREATE FUNCTION dbo.get_names_itvf (@user_id nvarchar(24))
RETURNS TABLE 
AS
RETURN
(SELECT dbo.usernames(@user_id) as username)
GO

如指定的那樣,返回表,因此 SQL 伺服器檢查表的底層結構,因為它需要知道開始返回的表類型。它有多少列,如果任何列沒有名稱(在聚合情況下)並通知您。如果使用者名表沒有指定的列名,您可以通過執行上面的查詢而不引用列名(‘as user name’)來測試這一點。

注意:我不得不稍微調整這兩個函式,以使它們工作。

希望這可以為您澄清幕後發生的事情

引用自:https://dba.stackexchange.com/questions/177487