KB4538581 - 修正:SQL Server 2022 和 2019 中的純量 UDF 內嵌問題

Applies To
SQL Server 2019 on Windows (all editions) SQL Server 2019 on Linux (all editions) SQL Server 2022 on Windows (all editions) SQL Server 2022 on Linux (all editions)

症狀

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_variant SQL 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_n SQL 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 定義只包含 GOTO SQL 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_ID SQL 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 的中繼資料:


/*

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 用來說明軟體更新的術語。