如何从函数(UDF)返回表变量?

Posted

技术标签:

【中文标题】如何从函数(UDF)返回表变量?【英文标题】:How to return a table variable from a function (UDF)? 【发布时间】:2014-06-26 17:18:43 【问题描述】:

我正在使用 SQL Server 2012,我一直在尝试许多不同的方法来从函数内部返回表变量,但我无法让它工作。我试过将变量声明移动到不同的地方,等等。这是 sql 的内容。如果可以的话,请将胆量包装在实际编译并返回 @Financials 表变量的 UDF 函数中,我将不胜感激。 sql很好用,没问题。但是当我尝试将它包装在 UDF 中时,它会在我尝试创建它时引发错误。我硬编码了一些东西,以便更容易测试和可视化。

DECLARE @Financials TABLE (
    [a bunch of variable declarations in here]
);

insert into @Financials
[big old SELECT query here - this all works fine, and populates @Financials]

    select * 
    from @Financials f1
    where f1.TransactionDate = (
        select MAX(TransactionDate)
        from @Financials
        where SalesDocumentItemID = f1.SalesDocumentItemID
    )

我现在需要 UDF 返回@Financials。

如果这是不可能的,请考虑我的真正问题,如上面@Financials 中的select * 所示,我只想匹配最新的TransactionDate,并由SalesDocumentItemID 加入。如果我能找到一种有效的方法来做到这一点,我根本不需要将 INSERT 插入到@Financials 中。我想问题是填充@Financials 的查询很复杂,有很多连接,我不想在子选择中再次复制所有这些。但我猜有一种很棒且更简单的方法可以做到这一点。会喜欢一些想法。

【问题讨论】:

您是否要让该功能在数据库中永久可用? 是的,永久 UDF。但我对其他选择持开放态度。 它抛出了什么错误? 【参考方案1】:

返回表变量时不要使用DECLARE。在RETURNS 子句中定义结果表。

CREATE Function GetFinancials ()
RETURNS @financials TABLE
(
  [a bunch of variable declarations in here]
)
AS
BEGIN
    insert into @Financials
    [big old SELECT query here - this all works fine, and populates @Financials]

    RETURN
END

更新

在存储过程中返回最终结果怎么样?

create procedure uspGetFinanicals
as
  declare @financial table
  (
    [table definition here]
  )

  insert into @financial
  select dbo.GetFinancials()

  select * 
    from @Financials f1
    where f1.TransactionDate = (
        select MAX(TransactionDate)
        from @Financials
        where SalesDocumentItemID = f1.SalesDocumentItemID
    )

更新

试试这个。在 UDF 中创建一个表变量来存储第一次选择的结果,然后将最终查询的结果插入到返回值中。

CREATE Function GetFinancials ()
RETURNS @financials TABLE
(
  [a bunch of variable declarations in here]
)
AS
BEGIN
    declare @table table([a bunch of variable declarations in here])
    insert into @table
    [big old SELECT query here - this all works fine, and populates @Financials]

    insert into @Financials
    select * 
      from @table f1
      where f1.TransactionDate = (
        select MAX(TransactionDate)
        from @table
        where SalesDocumentItemID = f1.SalesDocumentItemID
      )

    RETURN
END

【讨论】:

你让我非常接近,但我现在收到 1 个错误:“函数中包含的选择语句无法将数据返回给客户端。”它抱怨最后的 SELECT 语句在最后带有一个子选择。我该如何解决? @SweatCoder 正确 - 不允许选择。要制作您需要的子集,您必须限制插入“@financials”的数据,或者在插入后删除额外数据(前者相对便宜)。 嘿Sweat,你不能返回带有存储过程的表。 这应该是解决方案。不错的杰拉德。 它必须是一个函数,因为许多 proc 已经对它进行了选择,例如 SELECT * FROM Financials(1,2,3)。这个财务 UDF 已经存在,我只需要按照指示更改里面的 sql,这就是行不通的。

以上是关于如何从函数(UDF)返回表变量?的主要内容,如果未能解决你的问题,请参考以下文章

在 UDF 或存储过程中使用参数返回表

执行从 UDF 返回的语句时出现问题 - 没有结果集

如何从 arangodb udf 中的集合返回数据

从 UDF 返回 StructType 的 ArrayType 时出错(并在多个 UDF 中使用单个函数)

如何将UDF函数的返回值保存到两列?

SQL Server 用户定义函数返回表——不能从选择查询中调用它