症狀
User-Defined 以 Transact-SQL 實作且傳回單一資料值的函數 (UDF) 稱為 T-SQL 純量 User-Defined 函數 (UDF) 。
純量 UDF 內嵌功能是在 Microsoft SQL Server 2019 中引進的。 此功能可以改善叫用 T-SQL 純量 UDF 的查詢效能,其中 UDF 執行是主要瓶頸。 T-SQL 純量 UDF 內嵌會自動將可內嵌 UDF 轉換為關聯式運算式。
此累積更新 (CU) 包含下列方面的數個 修正程式, 適用於使用純量 UDF 內嵌的查詢可能會傳回錯誤訊息或意外結果的情況:
- 如果 UDF 的傳回類型是在
sql_variantSQL Server 2019 CU2) 中新增的 (,則會發生類型不相符錯誤。 - 取消
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_variant在 SQL Server 2019 CU7) 中新增的參數 (,則會發生明確轉換錯誤。 - 如果純量函數參照
CHECKSUM(SQL Server 2019 CU7) 中新增,則會發生錯誤。 - 具有許多純量運算式重新評估的 UDF 叫用可能會導致在 SQL Server 2019 CU7) 中新增 (非生成排程器錯誤。
注意:此問題的修正有時可能會導致效能下降。 若要緩解此效能回復,您可以開啟 TF) 13156 (追蹤旗標來停用原始修正程式。
Microsoft 正在努力修正此效能回復,並將在未來的 CU 中提供。 - 如果 UDF 參考查詢使用
OPTION (RECOMPILE)SQL Server 2019 CU7) 中新增的 (,則會發生錯誤。 - 如果檢視叫用內嵌 UDF (SQL Server 2019 CU9) 中新增,則會發生權限錯誤。
- 如果在 SQL Server 2019 CU9) 中使用 (新增 XEvent,就會
query_tsql_scalar_udf_inlined發生存取違規。 - 出現不一致的行為,是因為純量 UDF 內嵌不遵循
QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_nSQL Server 2019 CU9) 中新增的查詢提示 (。 - 內嵌 UDF 包含可能導致非生成排程器錯誤的彙總,這些錯誤 (SQL Server 2019 CU9) 中新增。
- 記憶體不足錯誤的發生原因是,在 SQL Server 2019 CU9) 中新增 (條件區塊中的相同變數上執行了一系列純量運算。
- 升級至 CU9 之後,如果物件叫用標量內嵌 UDF (UDF1) ,而該具有標量內嵌 UDF (UDF2) ,該是用來做為輸入參數 (在 SQL Server 2019 CU11) 中新增的,就會發生存取衝突。
- 內嵌 UDF 可能會導致錯誤,並產生錯誤碼 6846、1011 和 107, (SQL Server 2019 CU11) 中新增。
- 內嵌以非系統管理員帳戶執行的 UDF 可能會傳回錯誤訊息「目前命令發生嚴重錯誤。 如果有結果,則應丟棄」SQL Server 2019 年 CU16) 中新增 (。
- 如果使用在 Microsoft SQL Server 2022 CU1 和 SQL Server 2019 CU19) 中新增的同義字 (在 UDF 內叫用暫存資料表,就會發生存取衝突。
- 如果 UDF 定義只包含
GOTOSQL Server 2022 CU1 和 SQL Server 2019 CU19) 中新增的標籤和RETURN陳述式 (則會發生存取衝突。 - 當在 SQL Server 2022 CU3 和 SQL Server 2019 CU20) 中新增純量 UDF 內嵌功能時 (純量 UDF 會以不同的日期和時間格式傳回結果。
- 如果具有子
GROUP BY句的查詢在陳述式中使用SELECT內嵌 UDF,而沒有在 SQL Server 2022 CU12 和 SQL Server 2019 CU26) 中新增彙總函數 (則會產生傾印檔案。 - 即使巢狀層級未超過SQL Server 2022 CU12 和 (SQL Server 2019 CU26) 中新增 (,如果純量 UDF 內嵌功能已開啟,仍會發生「預存程序、函數、觸發程序或檢視巢狀層級上限超過限制 32) 」。
- 如果在 SQL Server 2022 CU12 和 SQL Server 2019 CU26) 中新增純量 UDF 內嵌功能 (新增,就會發生
sqllang.dll!CProchdr::FDeriveInlineabilityOfScalarUdf記憶體損毀。 - 由於純量 UDF 內嵌的組合,
OPTION (RECOMPILE)以及在 SQL Server 2022 CU17 和 SQL Server 2019 CU31) 中新增的相同查詢中 (產生不正確的結果。
此累積更新也會在下列案例中 封鎖 內嵌:
- 例如,
@@ROWCOUNT如果 UDF 參考某些內建函數 (,) 如果 UDF 內嵌 (新增到 2019 CU2) SQL Server中,則可能會改變結果。 - 如果彙總函數作為參數傳遞至純量 UDF (在 SQL Server 2019 CU2) 中新增。
- 如果 UDF 參考內建檢視 (例如:
OBJECT_IDSQL Server 2019 CU2) 中新增) (。 - 如果 UDF 使用 XML 方法, (SQL Server 2019 CU4) 中新增。
- 如果 UDF 包含
SELECT使用ORDER BY子句但未TOP 1(2019 CU4) 中新增的陳述式SQL Server。 - 例如,如果陳述式連同子句 (一起
ORDER BY執行指派,SELECT @x = @x +1 FROM table ORDER BY column_name則SELECT) (SQL Server 2019 CU4) 中新增。 - 如果 UDF 包含多個
RETURN陳述式, (SQL Server 2019 CU5) 中新增。 - 如果 UDF 是從 SQL Server 2019 CU5) 中新增的陳述式呼叫
RETURN(。 - 如果 UDF 參考
STRING_AGG函數 (SQL Server 2019 CU5) 中新增。 - 如果 UDF 定義參考遠端資料表, (SQL Server 2019 CU6) 中新增。
- 如果 UDF 呼叫查詢使用
GROUPING SETS、CUBE或ROLLUP(SQL Server 2019 CU6) 中新增。 - 例如,如果 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 的查詢具有通用資料表運算式 (CTE,則) (SQL Server 2019 CU11) 中新增。
- 如果 UDF 定義包含暫存資料表或暫存資料表的同義字,則 (SQL Server 2022 CU1 和 SQL Server 2019 CU19) 中新增。
- 如果 UDF 定義在
SELECT多個指派資料行上有一個陳述式以及DISTINCT子句,則 (SQL Server 2022 CU4 和 SQL Server 2019 CU20) 中新增。 - 如果 UDF 包含
SELECT使用TABLESAMPLE PERCENT子句的陳述式,並且 (在 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。 如需詳細資訊,請參閱 ALTER FUNCTION (Transact-SQL) 。
下列命令會產生指令碼來重新整理任何現有內嵌純量 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 的累積更新
SQL Server 的每個新累積更新都包含所有 Hotfix 和先前累積更新的所有安全性修正程式。 查看 SQL Server 的最新累積更新:
狀態
Microsoft 已確認「套用至」部分所列的 Microsoft 產品確實有上述問題。
參考資料
了解 Microsoft 用來說明軟體更新的術語。