用于从多列返回值的SQL函数

用于从多列返回值的SQL函数,sql,sql-server,user-defined-functions,Sql,Sql Server,User Defined Functions,我一直在开发一些存储过程,并且我一直在重复基于其他一些列派生列的部分代码。因此,我不想将这段代码从一个存储过程复制到另一个存储过程,而是考虑使用一个函数来获取输入列并生成输出列 基本上,功能如下所示: 从myTable中选择columnA、columnB、columnC、myFunction(columnA、columnB)作为columnD 正如我们所看到的,这个函数将A列和B列作为输入,然后返回D列 然而,根据一些研究,在使用像这样的UDF(用户定义)函数时,它似乎存在一些性能问题。这是真的

我一直在开发一些存储过程,并且我一直在重复基于其他一些列派生列的部分代码。因此,我不想将这段代码从一个存储过程复制到另一个存储过程,而是考虑使用一个函数来获取输入列并生成输出列

基本上,功能如下所示:

从myTable中选择columnA、columnB、columnC、myFunction(columnA、columnB)作为columnD

正如我们所看到的,这个函数将A列和B列作为输入,然后返回D列

然而,根据一些研究,在使用像这样的UDF(用户定义)函数时,它似乎存在一些性能问题。这是真的吗?处理这种情况的最好方法是什么


谢谢大家。

标量函数和多语句表值用户定义函数可能会导致性能问题,因为它们会隐式地将基于集合的操作转换为基于光标的操作

但是,内联表值用户定义函数不会遇到此问题。他们很快

区别在于如何声明函数,以及函数中的代码是什么样子的。多语句函数按照tin上的说明执行—它允许您拥有多个语句。像这样:

create function slow() returns @t table(j int, k int) as 
begin
    declare @j int = 1; -- statement 1
    declare @k int = 2; -- statement 2
    insert @t values (@j, @k); -- statement 3
    return; -- statement 4
end
内联表值函数不返回在函数内部填充的命名表。它返回一个select语句:

create function quick() returns table as
return
(
    select j = 1, k = 2
);
内联表值函数可以“内联”到外部select语句中,方式与视图大致相同。当然,区别在于UDF可以接受参数,而视图不能

您还必须以不同的方式使用它们。使用交叉应用:

select       t.columnA, t.columnB, u.j, u.k
from         MyTable t
cross apply  quick(t.columnA, t.columnB) u

如果不清楚-是的,在您的示例中,您只需要返回一个“标量”值,但这只是一个表值函数,返回一列和一行。因此,与其编写标量函数,不如编写一个执行相同任务的内联表值函数,然后交叉应用它。

信息如此之少,无法给出建议。这取决于你真正需要什么。即使是最小的函数也会自然地产生一些性能问题(例如:upper(myColumnA)),但值得对其进行优化以获得可能以纳秒为单位的时间,这一点值得商榷。如果你很担心的话,把这个问题留给前端吧。我最初在下面发布了我的答案,并没有明确说明如何替换标量用户定义函数(形式为
createfunctionfoo())使用内联表值函数将int返回为…
,以提高性能。不过,相同的参数仍然适用,因此我对答案进行了编辑,使其更加明确。您可以使用内联TVF返回“标量”值,交叉应用它,并且不会因为在select中使用真正的标量UDF而出现性能问题。这正是我想要澄清的!非常感谢@allmhuran@Kelvin另一个注意事项是,在最近(2019年)版本的SQL中,标量函数也可以在某些条件下内联,但现在看起来确实有点问题。