Когда вы используете табличную функцию?

В настоящее время я изучаю функции в sql-сервере, и я не понимаю, почему/когда вы будете использовать встроенную функцию оценки таблицы.

Я пробовал прочитать об этом и некоторые примеры, но мне все еще не ясно. Может ли кто-нибудь объяснить или предоставить простой для понимания сценарий использования?

Ответ 1

Табличнозначные функции - это "просто" параметризованные представления. Это делает их чрезвычайно мощными для инкапсуляции логики, которая иначе была бы скрыта за непрозрачной хранимой процедурой. Вот пример:

Встроенная табличная функция:

create function dbo.GetClients (
    @clientName nvarchar(50) = null
)
returns table
return (
    select *
    from dbo.Clients as a
    where ((a.ClientName = @clientName) or a.ClientName is null)
);

Сохраненная процедура:

create procedure dbo.usp_GetClients (
    @clientName nvarchar(50) = null
)
as
begin;
    select *
    from dbo.Clients as a
    where ((a.ClientName = @clientName) or a.ClientName is null)
end;

В отличие от вызова хранимой процедуры, функция, основанная на таблицах, позволяет мне составить логику из dbo.GetClients с другими объектами:

select *
from dbo.GetClients(N'ACME') as a
join ... as b
    on a.ClientId = b.ClientId

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

Встроенные табличные функции особенно впечатляют из-за "встроенного" бита, который, вероятно, лучше всего объясняется здесь. Это позволяет оптимизатору обрабатывать такие функции не иначе, как объекты, которые они инкапсулируют, что приводит к почти оптимальным планам производительности (при условии, что ваши индексы и статистика идеальны).

Ответ 2

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

В SQL-сервере у вас есть три вида пользовательских функций *: скалярные функции (svf), многострочные табличные функции (mTVF) и встроенные функции табличных значений (iTVF). svfs возвращает одно значение, и mTVF и iTVF возвращают таблицу. Разница между mTVF и iTVF - это производительность. Короче говоря, mTVF медленны, iTVF могут быть (и почти всегда) намного быстрее. mTVF позволяют делать то, что вы не могли сделать в представлении (например, создавать временные таблицы, выполнять циклы, использовать курсоры...), iTVF, опять же, имеют те же ограничения, что и представления, за исключением того, что они могут кроме параметров.

Я использую iTFV для обычных запросов хранилища данных, где мне нужно представление, которое принимает параметры и разбивает/обрабатывает строки. Более продвинутое использование iTVF, изменившее мою карьеру, заменяет скалярные функции на iTVF - см. Эту статью от Джеффа Модена под названием "Как заставить скалярные UDF запускать быстрее": http://www.sqlservercentral.com/articles/T-SQL/91724/

  • Для простоты я исключил тему CLR и других типов функций, отличных от T-SQL.