Встроенные скалярные функции: реальные или паровые?
Каков правильный синтаксис для создания встроенной скалярной функции в SQL Server?
Книги в Интернете, в главе Типы функций (2005 и выше), рассказывают о встроенных скалярных функциях, как будто они существуют, и как будто блок BEGIN...END
требуется (в отличие от многострочных функций):
Для встроенной скалярной функции нет тела функции; скалярный value - результат одного оператора. Для многостадийной скалярной функции тело функции, определенное в блоке BEGIN... END, содержит ряд операторов Transact-SQL, которые возвращают единственное значение.
Я также заметил строку для "IS: встроенная скалярная функция" в списке типов объектов в таблице spt_values:
SELECT name
FROM master..spt_values
WHERE type = 'O9T'
AND name LIKE '%function%'
Я попытался создать такую функцию без успеха:
CREATE FUNCTION AddOne(@n int) RETURNS int
AS
RETURN @n + 1
Сообщение об ошибке
Msg 102, уровень 15, состояние 31, процедура AddOne, строка 3 Неправильный синтаксис рядом с "RETURN".
Я что-то упустил или есть ошибка в онлайн-книгах?
Ответы
Ответ 1
Ну, AFAIK, ни один не существует (даже в скрытой [ mssqlsystemresource] базе данных), и нет синтаксиса для его создания. Таким образом, похоже, что Microsoft предвидит это в преддверии SQL Server 2005, добавив для него тип (и doc!), Но по какой-то причине он никогда не реализовывался.
Хотя это одна из самых популярных функций для всех серверов Ms Sql. В первую очередь потому, что UDF по умолчанию настолько медленный, и в итоге нам приходится работать с ITVF, чтобы получить тот же эффект. (сложный и неуклюжий, но он работает).
Ответ 2
Правильно, нет такой вещи, как встроенная скалярная функция. Можно "имитировать" с помощью встроенного TVF, однако синтаксис любых "клиентов" должен измениться.
1) создать его функцию:
create function dbo.AddOne(@input int) returns table as return (select @input + 1 as value);
2) в "клиентском" коде, сделайте это...
(select value from dbo.AddOne(Column)) as ColumnPlusOne
Теперь у вас есть действующая встроенная скалярная функция.
Мне пришлось сделать это, чтобы заменить множество скалярных UDF в моем клиентском коде, который выглядел так...
create function dbo.GetLookupID(@code varchar(50)) returns int
as
begin
declare @return int;
select @return = LookupID from dbo.Lookups where Code = @code;
return @return;
end;
Я попытался установить его, удалив переменную...
create function dbo.GetLookupID(@code varchar(50)) returns int
as
begin
return (select LookupID from dbo.Lookups where Code = @code);
end;
Это было улучшение, однако, все еще был неприятный удар производительности. Когда я перешел на iTVF и изменил соглашение о вызове... он стал намного лучше.
Ответ 3
Я вижу то же самое. Это предложение, по-видимому, является единственной ссылкой на "встроенные скалярные функции". В этой статье утверждается, что встроенные функции, основанные на таблице, могут быть достаточно быстрыми, чтобы выполнять задание.
Ответ 4
Начиная с SQL Server 2019 CTP2.1 появилась новая функция под названием "Скалярная UDF-вставка", которая может автоматически встраивать скалярные UDF при выполнении определенных предварительных условий.
Официальное сообщение в блоге, представляющее эту функцию, находится здесь: https://blogs.msdn.microsoft.com/sqlserverstorageengine/2018/11/07/introducing-scalar-udf-inlining/
Подробная документация, описывающая эту функцию, приведена здесь: https://docs.microsoft.com/en-us/sql/relational-databases/user-defined-functions/scalar-udf-inlining?view=azuresqldb-current