使用递归表值函数将行插入表变量

时间:2019-03-19 11:23:38

标签: sql sql-server tsql

CREATE function [dbo].[fnList](@id INT, @parent INT) RETURNS @res TABLE(
    [id] INT,
    [parent] INT,
    [parent_parent] INT,
    [amount] FLOAT,
    [cost] FLOAT,
    [table] VARCHAR(100)
)
BEGIN

    INSERT INTO @res
    SELECT * FROM SomeTable

    --Here I want to insert some more values

    INSERT INTO @res
    SELECT dbo.fnList(Results.id, Results.parent)
    FROM @res Results WHERE Results.[table] = 'SomeValue' AND Results.parent = @id

END

该函数是递归的。当我调用该函数时,出现错误:

  

找不到“ dbo”列或用户定义的函数,或者   聚合“ dbo.fnList”,或者名称不明确。

问题出在评论的最后一部分。我想在@res中插入多行。在res中,有表='SomeValue'和'OtherValue'的记录。对于第一个值,我想再次调用该函数。我该怎么做?

1 个答案:

答案 0 :(得分:0)

dbo.fnList是一个表值函数。您在内部对其进行调用,就好像它是一个标量函数一样。即

SELECT dbo.fnList(Results.id, Results.parent)

与以下正确语法相反:

SELECT * FROM dbo.fnList(Results.id, Results.parent)

当然,以上内容将不起作用,因为Results本身是表别名,而不是整数。因此,您需要一个游标来遍历结果并调用dbo.fnList。

即使您可以纠正语法,但是可以肯定的是,您很快就会遇到最大嵌套级别为32的问题?

  

用户定义的函数可以嵌套;也就是说,一个用户定义   函数可以调用另一个。当   被调用函数开始执行,并在被调用时递减   函数完成执行。用户定义的函数可以嵌套   到32级超过最大嵌套量会导致整体   调用功能链失败。

看起来您要么不得不在函数中添加很多循环,要么重新考虑解决方案。