Скалярные пользовательские функции для выполняющейся в памяти OLTP

Область применения: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure

В SQL Server 2016 (13.x) можно создавать и удалять собственные скомпилированные скалярные пользовательские функции. Вы также можете изменять эти пользовательские функции. Компиляция в собственном коде повышает производительность вычисления определяемых пользователем функций в Transact-SQL.

Если изменить скомпилированную в собственном коде скалярную определяемую пользователем функцию, приложение остается доступным при выполнении операции и компилируется новая версия функции.

Сведения о поддерживаемых конструкциях T-SQL см. в статье Поддерживаемые функции для модулей, скомпилированных в собственном коде T-SQL.

Создание, удаление и изменение определяемых пользователем функций

Вы используете CREATE FUNCTION для создания скомпилированной, скалярной определяемой пользователем функции, DROP FUNCTION для удаления определяемой пользователем функции и ALTER FUNCTION изменения функции. Инструкция BEGIN ATOMIC WITH требуется для определяемых пользователем функций.

Сведения о поддерживаемом синтаксисе и ограничениях см. в следующих статьях.

Хранимая процедура sp_recompile (Transact-SQL) может использоваться с скомпилированной, скалярной определяемой пользователем функцией. При этом произойдет повторная компиляция функции с использованием определения в метаданных.

В следующем примере показан скалярный UDF из примера базы данных AdventureWorks2022 .

CREATE FUNCTION [dbo].[ufnLeadingZeros_native](@Value int)   
RETURNS varchar(8)   
WITH NATIVE_COMPILATION, SCHEMABINDING  
AS   
BEGIN ATOMIC WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'English')  
  
    DECLARE @ReturnValue varchar(8);  
    SET @ReturnValue = CONVERT(varchar(8), @Value);  
       DECLARE @i int = 0, @count int = 8 - LEN(@ReturnValue)  
  
    WHILE @i < @count  
       BEGIN  
            SET @ReturnValue = '0' + @ReturnValue;  
            SET @i += 1  
       END  
  
    RETURN (@ReturnValue);  
  
END  

Вызов пользовательских функций

Скомпилированные в собственном коде скалярные определяемые пользователем функции можно использовать в выражениях там же, где и встроенные скалярные функции, и интерпретируемые скалярные определяемые пользователем функции. Скомпилированные в собственном коде скалярные определяемые пользователем функции можно также использовать с инструкцией EXECUTE, в инструкции Transact-SQL и в скомпилированной в собственном коде хранимой процедуре.

Эти скалярные определяемые пользователем функции можно использовать в скомпилированных в собственном коде хранимых процедурах и скомпилированных в собственном коде определяемых пользователем функциях, а также везде, где можно использовать встроенные функции. Кроме того, скомпилированные в собственном коде скалярные определяемые пользователем функции можно использовать в традиционных модулях Transact-SQL.

Эти скалярные пользовательские функции можно использовать в режиме взаимодействия везде, где можно использовать интерпретируемую скалярную пользовательскую функцию. В этом случае есть ограничения для транзакций между контейнерами, как описано в разделе Поддерживаемые уровни изоляции для транзакций между контейнерами статьи Операции с таблицами, оптимизированными для памяти. Дополнительные сведения о режиме взаимодействия см. в статье Доступ к таблицам, оптимизированным для памяти, с помощью интерпретируемых инструкций Transact-SQL.

Скомпилированным в собственном коде скалярным определяемым пользователем функциям требуется явно выраженный контекст выполнения. Дополнительные сведения см. в предложении EXECUTE AS (Transact-SQL). EXECUTE AS CALLER не поддерживается. Дополнительные сведения см. в статье EXECUTE (Transact-SQL).

Поддерживаемый синтаксис инструкций Transact-SQL Execute, для скомпилированных в собственном коде скалярных пользовательских функций см. в разделе EXECUTE (Transact-SQL). Сведения о поддерживаемом синтаксисе для выполнения определяемых пользователем функций в скомпилированной в собственном коде хранимой процедуре см. в статье Поддерживаемые функции для модулей, скомпилированных в собственном коде T-SQL.

Указания и параметры

Поддержка подсказок для таблиц, соединений и запросов в компилируемых в собственный код скалярных пользовательских функциях аналогична поддержке этих подсказок для компилируемых в собственный код хранимых процедур. Как и в случае с интерпретируемыми скалярными пользовательскими функциями, подсказки запроса, входящие в Transact-SQL запрос, ссылающиеся на нативно скомпилированную скалярную пользовательскую функцию, не влияют на план запроса для этой пользовательской функции.

Для скомпилированных в машинный код скалярных пользовательских функций поддерживаются все параметры, поддерживаемые для скомпилированных в машинный код хранимых процедур, если эти параметры допускаются для скалярных пользовательских функций. Пример поддерживаемого параметра — параметр с табличным значением.

Привязанный к схеме

Следующие сведения касаются скомпилированных в собственном коде скалярных определяемых пользователем функций.

  • Должен быть привязан к схеме с помощью аргумента WITH SCHEMABINDING в CREATE FUNCTION и ALTER FUNCTION.

  • Функцию нельзя удалить или изменить, если на нее ссылается хранимая процедура с привязкой к схеме или определяемая пользователем функция.

SHOWPLAN_XML

Собственно компилируемые скалярные пользовательские функции поддерживают SHOWPLAN_XML. Он соответствует общей схеме SHOWPLAN_XML, как и в случае с хранимыми процедурами, скомпилированными в собственный код. Базовый элемент определяемых пользователем функций — это <UDF>.

STATISTICS XML не поддерживается для скомпилированных в собственном коде скалярных пользовательских функций. При выполнении запроса, ссылающегося на определяемую пользователем функцию, с STATISTICS XML включенной, xml-содержимое возвращается без части для определяемой пользователем функции.

Разрешения

Как и в случае со скомпилированными в собственном коде хранимыми процедурами, разрешения для объектов, указанных в скомпилированной в собственном коде скалярной определяемой пользователем функции, проверяются при создании функции. CREATE FUNCTION завершается сбоем, если у пользователя, от имени которого выполняется действие, нет необходимых разрешений. Если во время изменения разрешений воплощаемый пользователь теряет соответствующие разрешения, последующее выполнение определяемой пользователем функции также завершается сбоем.

При использовании скомпилированной в собственном коде скалярной определяемой пользователем функции в скомпилированной в собственном коде хранимой процедуре разрешения на выполнение определяемой пользователем функции проверяются при создании внешней процедуры. Если у пользователя, олицетворенного внешней процедурой, нет разрешений EXEC для определяемой пользователем функции, происходит сбой создания хранимой процедуры. Если во время изменения разрешений пользователь теряет разрешения EXEC, происходит сбой выполнения внешней процедуры.