Проблема
User-Defined функции (UDF), реализованные в Transact-SQL и возвращающие одно значение данных, называются скалярными функциями User-Defined T-SQL (UDF).
Функция встраивания скалярной UDF появилась в Microsoft SQL Server 2019. Эта функция может повысить производительность запросов, вызывающих скалярные UDF T-SQL, в которых выполнение UDF является основным узким местом. T-SQL Скалярная функция встраивания пользовательской функции автоматически преобразует встраиваемые пользовательские функции в реляционные выражения.
Этот накопительный пакет обновления включает в себя несколько исправлений в следующих областях для сценариев, в которых запрос, использующий скалярную вставку пользовательских функций, может возвращать сообщение об ошибке или неожиданные результаты:
- Ошибка несоответствия типа возникает, если возвращаемым типом UDF является A
sql_variant(добавлено в SQL Server 2019 CU2). - Вызов UDF из
sp_executesqlотменяет выполнение (добавлено в SQL Server 2019 CU2). - Пользовательские функции, ссылающиеся на метки без связанной
GOTOкоманды, возвращают неправильные результаты (добавлено в SQL Server 2019 CU2). - Проблемы нехватки памяти и утечки памяти возникают из-за очень больших скалярных пользовательских функций (добавлено в SQL Server 2019 CU2).
- Неинициализированные переменные, используемые в операторах condition (
IF-ELSE), вызывают ошибки (добавляется в SQL Server 2019 CU2). - Ошибка явного преобразования возникает
sql_variant, если параметр есть у UDF (добавлен в SQL Server 2019 CU7). - Ошибка возникает, если скалярная функция ссылается на (
CHECKSUMдобавлено в SQL Server 2019 CU7). - Вызов UDF, который имеет много повторных оценок скалярных выражений, может привести к ошибке планировщика, не возвращающей данные (добавлено в SQL Server 2019 CU7).
Примечание. Исправление этой проблемы может иногда приводить к снижению производительности. Чтобы смягчить это снижение производительности, можно отключить исходное исправление, включив флаг трассировки (TF) 13156.
Корпорация Майкрософт работает над исправлением для этого снижения производительности, которое будет доступно в будущем CU. - Ошибка возникает, если в запросе ссылки на UDF используется
OPTION (RECOMPILE)(добавлено в SQL Server 2019 CU7). - Ошибки разрешений возникают, если представления вызывают встроенные пользовательские функции (добавлены в SQL Server 2019 CU9).
- Нарушения прав доступа происходят,
query_tsql_scalar_udf_inlinedесли используется XEvent (добавлен в SQL Server 2019 CU9). - Несогласованное поведение возникает из-за того, что скалярная подстановка пользовательской функции не учитывает подсказку запроса (добавлено
QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_nв SQL Server 2019 CU9). - Встраиваемые пользовательские функции содержат агрегаты, которые могут привести к ошибкам планировщика, не возвращающим данные (добавлено в SQL Server 2019 CU9).
- Ошибки, связанные с нехваткой памяти, возникают из-за последовательности скалярных операций с одной и той же переменной в условных блоках (добавлено в SQL Server 2019 CU9).
- После обновления до CU9 нарушение прав доступа происходит, если объект вызывает встраиваемую скалярную пользовательскую функцию (UDF1) с скалярной встраиваемой пользователем (UDF2), используемую в качестве входного параметра (добавлено в SQL Server 2019 CU11).
- Встраивание функций пользовательского режима может вызывать ошибки и генерировать ошибки с кодами 6846, 1011 и 107 (добавлено в SQL Server 2019 CU11).
- Встраивание пользовательских файлов, выполняемых от имени учетной записи, не являющейся учетной записью администратора, может вернуть сообщение об ошибке "В текущей команде произошла серьезная ошибка. Результаты, если таковые имеются, должны быть отброшены" (добавлено в SQL Server 2019 CU16).
- Нарушение прав доступа возникает, если временные таблицы вызываются внутри пользовательских функций с использованием синонимов (добавлено в Microsoft SQL Server 2022 CU1 и SQL Server 2019 CU19).
- Нарушение прав доступа возникает, если определение UDF содержит только
GOTOметки иRETURNинструкцию (добавляется в SQL Server 2022 CU1 и SQL Server 2019 CU19). - Скалярная UDF возвращает результаты в разных форматах даты и времени при включенной функции встраивания скалярной UDF (добавлено в SQL Server 2022 CU3 и SQL Server 2019 CU20).
- Файл дампа создается, если в запросе с предложением
GROUP BYв инструкции без агрегатной функции используются встроенные пользовательские функцииSELECT(добавлено в SQL Server 2022 CU12 и SQL Server 2019 CU26). - Ошибка «Превышен максимальный уровень вложенности хранимых процедур, функций, триггеров или представлений (ограничение 32)» возникает, если функция встраивания скалярных пользовательских функций включена, даже если уровень вложенности не превышен (добавлено в SQL Server 2022 CU12 и SQL Server 2019 CU26).
- Повреждение памяти происходит,
sqllang.dll!CProchdr::FDeriveInlineabilityOfScalarUdfесли включена функция встраивания скалярной UDF (добавлена в SQL Server 2022 CU12 и SQL Server 2019 CU26). - Неправильные результаты возникают из-за сочетания скалярного встраивания UDF и в одном запросе
OPTION (RECOMPILE)(добавлено в SQL Server 2022 CU17 и SQL Server 2019 CU31).
Этот накопительный пакет обновления также блокирует встраивание в следующих сценариях:
- Если функция пользовательской функции ссылается на некоторые встроенные функции (например, ), это может повлиять на результаты,
@@ROWCOUNTесли функция пользовательской функции встроена (добавлено в SQL Server 2019 CU2). - Если агрегатные функции передаются в качестве параметров в скалярную пользовательскую функцию (добавляется в SQL Server 2019 CU2).
- Если пользовательская функция ссылается на встроенные представления (например:
OBJECT_ID) (добавлено в SQL Server 2019 CU2). - Если в UDF используются методы XML (добавлено в SQL Server 2019 CU4).
- Если пользовательская
SELECTфункция содержит инструкцию, которая использует предложение,ORDER BYно неTOP 1(добавляется в SQL Server 2019 CU4). -
SELECTЕсли инструкция выполняет назначение вместе с предложениемORDER BY(например,SELECT @x = @x +1 FROM table ORDER BY column_name) (добавляется в SQL Server 2019 CU4). - Если UDF содержит несколько
RETURNинструкций (добавлено в SQL Server 2019 CU5). - Если определяемая пользователем функция вызывается
RETURNиз инструкции (добавленной в SQL Server 2019 CU5). - Если пользовательская функция ссылается на
STRING_AGGфункцию (добавлено в SQL Server 2019 CU5). - Если определение пользовательской функции ссылается на удаленные таблицы (добавлено в 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).
- Если пользовательские функции содержат ссылки на
WITH XMLNAMESPACES(добавлено в SQL Server 2019 CU11). - Если запрос, вызывающий пользовательскую функцию, содержит обобщенные табличные выражения (CTE) (добавлены в SQL Server 2019 CU11).
- Если определение пользовательской функции содержит временные таблицы или синонимы временных таблиц (добавлены в SQL Server 2022 CU1 и SQL Server 2019 CU19).
- Если определение пользовательской функции содержит
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).
После обновления до SQL Server 2019 CU2, но до обновления до SQL Server 2019 CU5 следует еще раз оценить, подходит ли пользовательская функция для встраивания. Для этого обновите соответствующие скалярные пользовательские функции с помощью одного из следующих способов:
- Запустите
sp_refreshsqlmoduleприменимые скалярные пользовательские функции. Дополнительные сведения об этой системной хранимой процедуре см. в статье sp_refreshsqlmodule (Transact-SQL). - Измените или повторно создайте существующую скалярную UDF, используя существующие определения, разрешения и свойства набора. Дополнительные сведения см. в статье ALTER FUNCTION (Transact-SQL).
Следующая команда создает сценарий для обновления метаданных всех существующих встроенных скалярных пользовательских файлов:
/*
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:
- Накопительный пакет обновления 17 для SQL Server 2022
- Накопительный пакет обновления 31 для SQL Server 2019
Сведения о накопительных обновлениях для SQL Server
Каждый новый накопительный пакет обновления для SQL Server содержит все исправления и исправления безопасности, которые входили в состав предыдущего накопительного пакета обновления. Ознакомьтесь с последними накопительными пакетами обновления для SQL Server:
- Последний накопительный пакет обновления для SQL Server 2022
- Последний накопительный пакет обновления для SQL Server 2019
Состояние
Корпорация Майкрософт подтвердила, что эта проблема возникает в продуктах Майкрософт, перечисленных в разделе «Относится к».
Ссылки
Узнайте о терминологии, используемой корпорацией Майкрософт для описания обновлений программного обеспечения.