Sql server SQL Server中的类递归查询

Sql server SQL Server中的类递归查询,sql-server,tsql,stored-procedures,Sql Server,Tsql,Stored Procedures,我试图弄清楚如何在SQL中执行本质上是递归查询的操作。我有两张桌子 TABLE Object( id INT NOT NULL PRIMARY KEY ) TABLE ObjectDependency( object_id INT, dependency_id INT, FOREIGN KEY(object_id) REFERENCES Object(id) FOREIGN KEY(dependency_id) REFERENCES Object(id) ) 我想编写一个存储过程,它

我试图弄清楚如何在SQL中执行本质上是递归查询的操作。我有两张桌子

TABLE Object(
id INT NOT NULL PRIMARY KEY
)

TABLE ObjectDependency(
object_id INT,
dependency_id INT,
FOREIGN KEY(object_id)     REFERENCES Object(id)
FOREIGN KEY(dependency_id) REFERENCES Object(id)
)
我想编写一个存储过程,它将获取一个对象id并吐出所有对象依赖项(类似于这样的内容,但也包括任何找到的依赖项的依赖项)

SELECT id, ObjectDependency.id FROM Object
JOIN ObjectDependency ON object_id = id 

系统的设置方式不存在周期依赖性,但我对如何将所有结果循环到一个存储过程有点迷茫。

如果您使用的是SQL Server 2005或更新版本,则可以使用递归CTE(公共表表达式)来执行此操作(有关更多详细信息,请参阅)

基本上,它是一个“内联视图”——一个只存在于下一条语句中的视图。CTE的一个版本是专门为处理递归场景而设计的

它看起来像这样:

CREATE PROCEDURE dbo.RecurseObjects @ObjectID INT
AS BEGIN
  WITH ObjectCTE AS 
  (
      -- set the anchor - select the object defined
      SELECT o.id AS 'ID', CAST(NULL AS INT) AS 'ParentID', 1 AS 'Level'
      FROM dbo.Object o
      WHERE o.id = @ObjectID

      -- add recursion
      UNION ALL

      SELECT o2.id AS 'ID', cte.id AS 'ParentID', cte.Level + 1 AS 'Level'
      FROM dbo.Object o2
      INNER JOIN dbo.ObjectDependency od ON od.dependency_id = o2.id
      INNER JOIN ObjectCTE cte ON cte.id = od.object_id
  )
  SELECT *
  FROM ObjectCTE
END
object.id --> objectdepedency.dependecy_id 
              objectdepedency.object_id --> "parent" object.id
因此,此递归CTE分阶段运行:

  • 第一次“运行”设置锚定,即执行第一次
    SELECT
    ,并将结果存储在临时结果集中
  • 然后,处理递归:运行第二次选择,基本上从第一次运行中选择的行中选择所有依赖的行-所有链接如下的行:

    CREATE PROCEDURE dbo.RecurseObjects @ObjectID INT
    AS BEGIN
      WITH ObjectCTE AS 
      (
          -- set the anchor - select the object defined
          SELECT o.id AS 'ID', CAST(NULL AS INT) AS 'ParentID', 1 AS 'Level'
          FROM dbo.Object o
          WHERE o.id = @ObjectID
    
          -- add recursion
          UNION ALL
    
          SELECT o2.id AS 'ID', cte.id AS 'ParentID', cte.Level + 1 AS 'Level'
          FROM dbo.Object o2
          INNER JOIN dbo.ObjectDependency od ON od.dependency_id = o2.id
          INNER JOIN ObjectCTE cte ON cte.id = od.object_id
      )
      SELECT *
      FROM ObjectCTE
    END
    
    object.id --> objectdepedency.dependecy_id 
                  objectdepedency.object_id --> "parent" object.id
    

第二步将反复执行,直到不再检索其他行为止-然后返回结果集。

如果您有权访问递归CTE…;-)对此,不同的数据库产品有不同的解决方案(Oracle/Mysql/PostgreSQL/MS SQL/…)。你在使用哪一个?SQL Server,对不起,我对数据库的世界有点迷茫。看看你在使用哪个版本的SQL Server??