【问题标题】:Writing Recursive StoredProcedures编写递归存储过程
【发布时间】:2010-10-30 10:40:28
【问题描述】:

基本上我想要在我的存储过程中返回一个表列表,将这个列表存储在一个变量中;我需要遍历列表中的每个项目以递归调用此存储过程。最后,我需要一个由这个递归构建的整体 listOfTables。 任何帮助将不胜感激

【问题讨论】:

  • 你能提供一个查询和/或输出的例子吗?

标签: tsql variables recursion list


【解决方案1】:

如果您使用的是 SQL2005 或更高版本,您应该查看Common Table Expressions(不确定它们是否可以帮助您解决特定情况,但它是大多数递归查询的重要替代方案)。递归过程的嵌套深度不能超过 32 层,而且不是很优雅。

【讨论】:

    【解决方案2】:

    你可以使用CTE的:

    WITH  q (column1, column2) (
            SELECT  *
            FROM    table
            UNION ALL
            SELECT  *
            FROM    table
            JOIN    q
            ON      …
            )
    SELECT   *
    FROM     q
    

    但是,有不同的限制:您不能使用聚合、分析函数、TOP 子句等。

    【讨论】:

      【解决方案3】:

      你是在递归之后还是只是在所有表中循环?如果您使用的是 Sql Server 2005 并且想要遍历所有表,您可以在 SP 中使用表变量,请尝试以下几行:

      declare @TableList as table (
          ID int identity (1,1),
          TableName varchar(500)
      )
      
      insert into @TableList (TableName)
      select name
      from sys.tables
      
      declare @count int
      declare @limit int
      declare @TableName varchar(500)
      
      set @count = 1
      select @limit = max(ID) from @TableList
      
      while @count <= @limit
          begin
              select @TableName = TableName from @TableList where ID = @count
              print @TableName --replace with call to SP
      
              set @count = @count + 1
          end
      

      print @TableName 替换为对 SP 的调用,如果您不希望它在数据库中的每个表上运行,则将查询 select name from sys.tables 更改为仅返回您之后的表

      【讨论】:

        【解决方案4】:

        CTE 很可能会满足您的要求。

        如果您确实必须使用存储过程而不是查询,那么您所要做的就是遍历表列表,然后您可以使用您选择的代码来遍历表列表并调用该过程。并且宏已经在我输入大声笑时发布了如何做到这一点。正如 Mehrdad 已经告诉您的,SQL Server 允许的嵌套调用级别的数量是有限的,而且相当浅。从您的解释中我不相信您需要递归调用,它看起来更像是对列表的简单迭代,但如果您确实需要递归,请记住 CS 101 类:any recursive algorithm can be transformed into a non-recursive one by using a loop iteration and a stack

        【讨论】:

        • 这是一把双刃剑——有可能得到一个无限循环。不可能有无限递归。
        【解决方案5】:

        存储过程非常有用。但是。

        我最近不得不在一个严重依赖存储过程的系统上工作。这是一场噩梦。一半的业务逻辑使用一种语言(在本例中为 Java),另一半在数据库中的存储过程中。更糟糕的是,一半的应用程序处于源代码控制之下,而另一半是由于永久丢失而导致的数据库崩溃(糟糕的备份过程)。另外,我拥有的所有用于扫描、分析和维护源代码的可爱小工具都无法使用数据库中的源代码。

        我并不是天生就反对存储过程,但是哦,它们怎么会被滥用。当您需要对来自多个来源的数据执行规则时,存储过程非常适合,并且没有更好的方法可以将繁重的记录访问从网络服务器(并转移到 DBMS 服务器上)卸载。但在大多数情况下,我宁愿使用视图而不是存储过程和业务逻辑的应用程序编程语言。我知道这会让一些事情变得更复杂一些。但它可以让生活变得更轻松。

        【讨论】:

          猜你喜欢
          • 2015-08-08
          • 2013-11-13
          • 1970-01-01
          • 2012-07-21
          • 2020-08-07
          • 1970-01-01
          • 2023-04-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多