你什么时候使用表值函数?

时间:2016-11-10 19:27:41

标签: sql sql-server tsql

我目前正在学习sql server中的函数,我不明白为什么/何时使用inline table valued function

我试过阅读它和一些例子,但我仍然不清楚。有人可以解释或提供易于理解的用例场景吗?

2 个答案:

答案 0 :(得分:22)

表值函数是“仅”参数化视图。这使得它们非常强大,可以封装逻辑,否则这些逻辑将隐藏在不透明的存储过程之后。这是一个例子:

内联表值函数:

create function dbo.GetClients (
    @clientName nvarchar(max) = 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(max) = 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

在这种情况下,我无法想象使用存储过程,因为与表值函数相比它具有多么严格的限制。我将被迫使用临时表,表变量或应用程序层来编组自己周围的数据,以便组合来自多个对象的结果。

内联表值函数特别棒,因为“内联”位可能是最好的解释here。这允许优化器处理这些函数与它们封装的对象没有什么不同,从而产生接近最优的性能计划(假设您的索引和统计数据是理想的)。

答案 1 :(得分:6)

这是一个很好的问题和一个没有充分讨论的话题恕我直言。将内联表值函数视为接受参数的视图。这是简短的答案,但让我们深入挖掘......

在SQL服务器中,您有三种用户定义的函数*:标量函数(svf),多行表值函数(mTVF)和内联表值函数(iTVF)。 svfs返回单个值,mTVF和iTVF都返回一个表。 mTVF和iTVF之间的区别在于性能。简而言之 - mTVF很慢,iTVF可以(并且几乎总是)更快。 mTVF允许你做一些你在视图中无法做的事情(例如创建临时表,执行循环,利用游标......),iTVF再次具有与视图相同的限制,除了它们可以除了参数。

我使用iTFV进行常见的数据仓库查询,我需要一个带参数和拆分/操作字符串的视图。更高级的iTVF使用已经改变了我的职业生涯正在用iTVF取代标量函数 - 请参阅Jeff Moden撰写的题为“如何使标量UDF运行得更快”的文章:http://www.sqlservercentral.com/articles/T-SQL/91724/

  • 为简单起见,我排除了CLR和其他非T-SQL类型函数的主题。