Sql-Server
TSQL - 由使用者定義函式 (UDF) 返回並在內聯表值函式 (iTVF) 中使用的中間結果
我最近遇到了這個問題,想知道我的理解是否正確。我的 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
這就是我為我的數據庫創建所有函式的方式:
- 我從
sysobjects
- 我再次重新創建所有功能。
- “該
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’)來測試這一點。
注意:我不得不稍微調整這兩個函式,以使它們工作。
希望這可以為您澄清幕後發生的事情