SQL Server 中的表、行值 UDF

Posted

技术标签:

【中文标题】SQL Server 中的表、行值 UDF【英文标题】:Table, Row valued UDFs in SQL Server 【发布时间】:2020-12-08 05:10:27 【问题描述】:

SQL Server(和其他一些数据库)支持Table-value function。是否存在诸如行值函数之类的东西——基于一组输入值,将返回特定行,或者不支持该类型的函数类型。如果不支持,为什么不支持?

SQL Server 给出的例子是:

CREATE FUNCTION ProductsCostingMoreThan(@cost money)  
RETURNS TABLE  
AS  
RETURN  
    SELECT ProductID, UnitPrice  
    FROM Products  
    WHERE UnitPrice > @cost  

所以行值函数可能看起来像(我想):

CREATE FUNCTION GetCalculatedRow(@pk)
RETURNS ROW
AS
RETURN
    SELECT * FROM Products
    WHERE id=@pk

也许这没有意义(因为很容易有不同的行形状),但我只是好奇这种东西是否受支持?我想它相当于一个相关的子查询,所以它可能有用(或至少方便)。

【问题讨论】:

快速回答:没有。为什么?好的,为什么我们需要一个只返回一行的函数,而我们已经有一个可以返回 1 行或更多行的函数。 @Ilyes - 我想围绕只允许一行的相关子查询方便?还是表格函数可以做到这一点? @samuelbrody1249,无论它内部的查询返回什么,表函数都可以返回 0、1 或更多行。您可以编写查询SELECT TOP(1) * FROM Products WHERE id=@pk 以保证它不会返回超过 1 行(它仍然可以返回 0 行)。在更广泛的查询中使用这样的函数可能不是很有效。您是否有一些特定的问题要解决,或者只是一般的好奇心?当前的表值函数比“行值函数”更通用,因此很难证明需要此功能。 @VladimirBaranov 只是一个普遍的好奇心——如果这是一个“东西”或者它总是由一个表值函数(或其他东西)处理。 SQL Server 没有“行值”函数。您有只返回一个值的标量函数或返回具有明确定义的模式和任意数量的行(0 或更多)的表的表值函数。您还可以使用 [相关] 子查询和/或横向连接(SQL Server 中的CROSS / OUTER APPLY)。 【参考方案1】:

SQL Server 中有两种类型的函数:

返回单个值的标量函数(即“标量”) 返回多行或多个值的表值函数。

您所描述的只是表值函数的一种变体,它只返回一行(或者可能没有行,这在您的示例中是可能的)。

你可以调用这样的函数:

select . . .
from t outer apply
     dbo.rowfunc( . . . )

或者:

select *
from t left join
     dbo.rowfunc ( . . . )
     on 1=1

或者:

select *
from db.rowfunc( . . . )

即使没有返回行,前两个返回值也是如此。第三个没有这种可能性(很容易)。

请注意,某些数据库支持“元组”,这就是(我猜)您所说的“行”的意思——单个“标量”值中的多个列。 SQL Server 不是其中之一。

但是,如果您想返回多个值,您可以使用 JSON 或 XML 模拟元组。

【讨论】:

感谢您。几个问题:支持 tuple 的 DBMS 示例是什么? outer apply 有什么作用? Postgres 是一个支持元组的数据库示例。 outer apply 实现了横向连接,这很像可以返回多列和多行的相关子查询。 谢谢,Postgres 中的元组有链接吗?我在谷歌上搜索了一下,它没有作为一种类型出现。 @samuelbrody1249 。 . . Postgres 称它们为“行构造函数”(postgresql.org/docs/current/…)。但是,您需要了解它们如何与比较操作和in 一起使用。 Postgres 也有复合类型,所以行构造函数就像“匿名”复合类型。

以上是关于SQL Server 中的表、行值 UDF的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL Server 的表列中使用 UDF 作为默认值

SQL Server 2008 - UDF 参数类型和返回类型

MS SQL Server 中的标量 UDF 在查询中仅返回一个值

从 VB Access 调用 UDF(Sql server)“表达式中的未定义函数 <函数名>”

SQL Server 2005 标量 UDF 性能

SQL Server UDF 数组输入和输出