如何使用递归函数更新表?

Posted

技术标签:

【中文标题】如何使用递归函数更新表?【英文标题】:How to use a recursive function to update a table? 【发布时间】:2010-09-27 15:56:18 【问题描述】:

这是this question的后续报道。

函数不允许写入数据库,但如果我想在每次调用函数时更新记录怎么办,特别是递归函数?

目前,我有一个接受 ID 并返回浮点数的函数。我想使用给定的 ID 和返回的浮点数更新表。通常,可以使用一个简单的存储过程来调用该函数,然后进行更新。我的函数是递归的,所以解决方法没那么简单……

我正在考虑尝试这样做:

创建递归函数,以便将表作为参数 如果表为空,则创建它;否则,将表复制到一个新变量(因为它将是只读的) 在进行递归调用之前更新函数中复制的表,并将副本传递给函数 最后,返回完整的表格(不确定我如何“知道”它是否完整) 从使用返回的表进行多次更新的存储过程调用此函数

在尝试类似的方法之前,我正在寻找替代方案。好像以前也有过。

【问题讨论】:

为什么“调用函数”/“将返回值写入表”模型不适用于您的递归函数? 对于什么版本的 SQL Server?更多细节会有所帮助 @Tomalak 每次调用函数时我都需要写返回值,而不仅仅是递归函数返回的最终值。 【参考方案1】:

任何递归实现都是T-SQL迟早会碰到@@NESTLEVEL cap:

您可以嵌套存储过程和 托管代码引用多达 32 个 水平。嵌套级别增加 一、当调用存储过程 或托管代码引用开始 执行并减一时 被调用的存储过程或托管 代码引用完成执行。 试图超过最大值 32 嵌套层次导致整体 调用链失败。

但是我们从 CS101 知道,任何递归算法都可以在堆栈的帮助下实现为迭代算法。所以你需要一个表来充当堆栈(有关一些相关讨论,请参阅Using Tables as Queues)。使用存储过程,而不是函数,因为在 T-SQL 中“函数”是特殊的(基本上是数据访问路径)并且不允许修改数据。每当您想到“函数”(如在 C/C++/C# 函数或方法中)时,您确实需要一个存储过程。您不能从过程中返回“表”,因此输出必须是您将结果写入其中的表。

所有这些都只是理论,因为您没有提供实际问题,只是对问题类型的描述。如果我们知道真正的问题,我们可能会说存储过程是否有意义,是否可以使用游标,是否使用#temp 表是可行的方法等等。所有这些只是为了考虑普通的香草算法。如果您添加数据大小注意事项和并发问题,事情可能会真的变得棘手。

【讨论】:

感谢您的回复。该系统的设计将不需要 32 级递归。我确实喜欢指定一个表用作堆栈的想法......我需要一个互斥锁来只允许这个过程在任何给定时间运行 1 个实例。也有可能等待调用 SP 的客户端在活动 SP 完成后可能不需要... 对于这个问题,使用存储过程和堆栈是一个很好的解决方案。谢谢 对互斥锁使用 sp_getapplock:msdn.microsoft.com/en-us/library/ms189823.aspx (+1) for “因为在 T-SQL 中......每当你想到‘函数’(如在 C/C++/C# 函数或方法中),你真的需要一个存储过程。”对于其余内容,这个答案值得另一个(+1),但不能添加......

以上是关于如何使用递归函数更新表?的主要内容,如果未能解决你的问题,请参考以下文章

如何加快递归搜索功能?

如何在excel表中计算递归函数?

如何使函数递归

如何使用递归方法更新python字典

mysql递归查询

php写函数 根据子类(id)递归查找顶级父类(id) 返回父类名字 (表结构:id name pid)