徵兆
User-Defined 函數 (在 Transact-SQL 中實作且傳回單一數據值的 UDF) 稱為 T-SQL Scalar User-Defined 函數 (UDFs) 。
Scalar UDF Inlining 功能於 2019 年 Microsoft SQL Server 推出。 此功能可以改善呼叫 T-SQL Scalar UDFs 的查詢效能,其中 UDF 執行是主要瓶頸。 T-SQL Scalar UDF Inlining 會自動將內嵌 UDF 轉換成關係型表達式。
針對使用 Scalar UDF Inlining 的查詢可能會傳回錯誤訊息或非預期的結果,此累積更新 (CU) 包含下列各區域的數個 修正 :
-
如果UDF的傳回類型是 SQL Server 2019 CU2) 中新增的 sql_variant (,就會發生類型不相符的錯誤。
-
從sp_executesql叫用 UDF 會取消在 SQL Server 2019 CU2) 中新增的執行 (。
-
參照沒有相關聯 GOTO 命令之標籤的 UDF 會傳回 (在 SQL Server 2019 CU2) 中新增的錯誤結果。
-
因為在 SQL Server 2019 CU2) 中新增的刻度 UDF (很大,因此發生記憶體不足狀況和記憶體洩漏。
-
在條件 (IF-ELSE) 語句中使用的未初始化變數會造成錯誤 (新增至 SQL Server 2019 CU2) 。
-
如果 UDF 在 SQL Server 2019 CU7) 中新增 sql_variant參數 (,就會發生明確轉換錯誤。
-
如果在 SQL Server 2019 CU7) 中新增的刻度函數參照 CHECKSUM(,就會發生錯誤。
-
在 SQL Server 2019 CU7) 中新增的 UDF 語句具有許多縮放運算式重新評估,可能會導致非收益的排程器錯誤 (。
注意:這個問題的修正程式有時可能會導致效能回歸。 若要降低此效能回歸,您可以開啟追蹤標幟 (TF) 13156 來停用原始修正程式。
Microsoft正在努力修正此效能回歸問題,在未來的 CU 中將會提供此修正程式。
-
如果 UDF 參照查詢使用在 SQL Server 2019 CU7) 中新增的 OPTION (RECOMPILE)(,就會發生錯誤。
-
如果在 SQL Server 2019 CU9) 中新增了叫用內嵌 UDF 的檢視 (,就會發生許可權錯誤。
-
如果使用query_tsql_scalar_udf_inlinedXEvent (在 SQL Server 2019 CU9) 中新增,就會發生違反存取的情事。
-
發生不一致的行為是因為 Scalar UDF Inlining 不尊重 SQL Server 2019 CU9) 中新增的 QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_n查詢提示 (。
-
內嵌 UDF 包含可能會在 SQL Server 2019 CU9) 中新增 (可能導致非收益排程器錯誤的匯總。
-
因為在 SQL Server 2019 CU9) 中新增之條件區塊 (的相同變數上,發生記憶體不足的錯誤。
-
升級至 CU9 之後,如果物件叫用的縮放式無線 UDF (UDF1) 具有可縮放式 UDF (UDF2) 做為輸入參數, (新增至 SQL Server 2019 CU11) ,則會發生存取違規。
-
將 UDF 加入 SQL Server 2019 CU11) 中,可能會造成錯誤併產生錯誤碼 6846、1011 和 107 (。
-
以非 sysadmin 帳戶執行的內建 UDF 可能會傳回錯誤訊息:「目前命令發生嚴重錯誤。 SQL Server 2019 CU16) 中 (應該捨棄) 的結果。
-
如果使用 Microsoft SQL Server 2022 CU1 和 SQL Server 2019 CU19) 中新增的同義字 (在 UDF 內叫用暫存數據表,就會發生存取違規。
-
如果 UDF 定義只包含 GOTO 標籤,以及 SQL Server 2022 CU1 和 SQL Server 2019 CU19) 中新增的RETURN 語 (句,即會發生存取違規。
-
當在 SQL Server 2022 CU3 和 SQL Server 2019 CU20) 中新增的 Scalar UDF Inlining 功能開啟 (時,Scalar UDF 會傳回不同的日期和時間格式。
-
如果具有 GROUP BY 子句的查詢在 SELECT 語句中使用內嵌 UDF,而沒有在 SQL Server 2022 CU12 和 SQL Server 2019 CU26) 中新增匯總函數 (,就會產生轉儲檔案。
-
開啟 Scalar UDF Inlining 功能時,發生錯誤「巢狀層級上限超過 (限制 32) 」,即使巢狀層級未超過 (SQL Server 2022 CU12 和 SQL Server 2019 CU26) 中新增的巢狀層級也一樣。
-
如果已在 SQL Server 2022 CU12 和 SQL Server 2019 CU26) 中新增 (開啟 Scalar UDF Inlining 功能, sqllang.dll!CProchdr::FDeriveInlineabilityOfScalarUdf 中就會發生記憶體損毀。
-
發生錯誤的結果是因為在 SQL Server 2022 CU17) 中新增的相同查詢 (中,Scalar UDF inlining 和 OPTION (RECOMPILE) 的組合。
此累積更新也會 在下列案例中封鎖內置:
-
例如,如果 UDF 參照 (某些內嵌函數, @@ROWCOUNT) 在 SQL Server 2019 CU2) 中新增的 UDF 內嵌 (可能會變更結果。
-
如果匯總函數是以參數的形式傳遞至 SQL Server 2019 CU2) 中新增的縮放 UDF (。
-
例如,如果 UDF 參照內建檢視 (:SQL Server 2019 CU2) 中新增 OBJECT_ID) (。
-
如果 UDF 使用 (SQL Server 2019 CU4) 中新增的 XML 方法。
-
如果 UDF 包含使用ORDER BY子句但未 TOP 1(在 SQL Server 2019 CU4) 中新增的 SELECT語句。
-
例如,如果SELECT 語句會與 ORDER BY 子句 (一起執行作業, SELECT @x = @x +1 FROM table ORDER BY column_name) (在 SQL Server 2019 CU4) 中新增。
-
如果 UDF 包含 (SQL Server 2019 CU5) 中新增的多個 RETURN 語句。
-
如果從 SQL Server 2019 CU5 () 新增的 RETURN 語句來撥打 UDF。
-
如果 UDF 參照 SQL Server 2019 CU5) 中新增的 STRING_AGG 函數 (。
-
如果 UDF 定義參照 (在 SQL Server 2019 CU6) 中新增的遠端資料表。
-
如果 UDF 通話查詢使用 SQL Server 2019 CU6) 中新增的 GROUPING SETS、 CUBE或 ROLLUP (。
-
例如,如果 UDF 通話查詢包含做為工作分派 (UDF 參數的變數, SELECT @y=2, @x=UDF(@y)) (在 SQL Server 2019 CU6) 中新增。
-
如果 UDF 參照加密的欄 (在 SQL Server 2019 CU11) 中新增。
-
如果 UDF 包含在 SQL Server 2019 CU11) 中新增的 WITH XMLNAMESPACES(參照。
-
如果叫用 UDF 的查詢有在 SQL Server 2019 CU11) 中新增 (CTEs) (的通用數據表表達式。
-
如果 UDF 定義包含臨時表格的臨時表格或同義字, (在 SQL Server 2022 CU1 和 SQL Server 2019 CU19) 中新增。
-
如果 UDF 定義具有SELECT語句,以及在 SQL Server 2022 CU4 和 SQL Server 2019 CU20) 中新增 (多個工作分派欄的DISTINCT子句。
-
如果 UDF 包含使用 TABLESAMPLE PERCENT 子句的 SELECT 語句,以及在 SQL Server 2022 CU7 () 中新增的多個變數指派。
-
如果索引檢視所參照的數據表上存在 INSERT 查詢,該數據表包含在 SQL Server 2022 CU12 和 SQL Server 2019 CU26) 中新增的 UDF (。
升級至 SQL Server 2019 CU2 之後,但在升級至 SQL Server 2019 CU5 之前,您應該重新評估 UDF 是否符合輸入的資格。 若要這麼做,請透過下列其中一種方法重新整理合格的縮放UDF:
-
針對適用的縮放 UDF 執行 sp_refreshsqlmodule 。 如需此系統儲存程式的詳細資訊,請參閱 sp_refreshsqlmodule (Transact-SQL)。
-
使用現有的定義、許可權和設定屬性來變更或重新建立現有的刻度 UDF。 如需詳細資訊,請 參閱 Transact-SQL (ALTER FUNCTION)。
下列命令會產生腳本,以重新整理任何現有內嵌縮放 UDF 的元資料:
/*
Generates a script that can be used to refresh all active inlineable scalar UDFs.
Note The sp_refreshsqlmodule command does not affect any permissions, extended properties, or SET options that are associated with the object.
*/
SELECT 'EXECUTE sys.sp_refreshsqlmodule ''[' + OBJECT_SCHEMA_NAME(object_id) + +'].' + '[' + OBJECT_NAME(object_id)
+ ']'';' AS 'RefreshStatement'
FROM sys.sql_modules
WHERE is_inlineable = 1
AND inline_type = 1;
GO
注意:在您升級至 SQL Server 2019 CU5 之後,我們會在編譯期間繼續自動衍生 UDF 內嵌性。
解決方案
此問題已在下列 SQL Server 累積更新中修正:
SQL Server 的每個新累積更新都包含所有 Hotfix 以及先前累積更新隨附的所有安全性修正。 檢視 SQL Server 的最新累積更新:
狀態
Microsoft 已確認<適用於>一節中所列的 Microsoft 產品確實有上述問題。
參考
了解 Microsoft 用來說明軟體更新的術語。