sql-server - 如何使用存储过程在 SQL Server 2005 中使用 CTE 从分层数据中获取所有子项及其本身

标签 sql-server stored-procedures common-table-expression hierarchical

我有很多类似这样的结构表:

CREATE TABLE [dbo].[tbl_Hierarchy](
[ID] [int]  NOT NULL,
[ParentID] [int] NOT NULL,
[Text] [nvarchar](100)  NOT NULL,
--other field irrelevant to my question
)

INSERT INTO dbo.tbl_Hierarchy VALUES(1,0,'parent1')
INSERT INTO dbo.tbl_Hierarchy VALUES(2,0,'parent2')
INSERT INTO tbl_Hierarchy VALUES(3,1,'child1')
INSERT INTO tbl_Hierarchy VALUES(4,3,'grandchild1')
INSERT INTO  tbl_Hierarchy VALUES(5,2,'child2')

你能帮我写一个包含表名和ID两个参数的存储过程吗?

例如执行时

EXEC usp_getChildbyID  tbl_Hierarchy, 1

结果集应该是:

ID  Text        Level
1   parent1      1
3   child1       2
4   grandchild1  3

非常感谢。

最佳答案

这个递归 CTE 应该可以解决问题。

WITH RecursiveCte AS
(
    SELECT 1 as Level, H1.Id, H1.ParentId, H1.Text FROM tbl_Hierarchy H1
    WHERE id = @Id
    UNION ALL
    SELECT RCTE.level + 1 as Level, H2.Id, H2.ParentId, H2.text FROM tbl_Hierarchy H2
    INNER JOIN RecursiveCte RCTE ON H2.ParentId = RCTE.Id
)
SELECT Id, Text, Level FROM RecursiveCte

如果你真的想在过程中使用动态表,这可能是一个解决方案

CREATE PROCEDURE usp_getChildbyID
    @TableName nvarchar(max),
    @Id int
AS
BEGIN

    DECLARE @SQL AS nvarchar(max)
    SET @SQL = 
    'WITH RecursiveCte AS
    (
        SELECT 1 as Level, H1.Id, H1.ParentId, H1.Text FROM ' + @TableName + ' H1
        WHERE id = ' + CAST(@Id as Nvarchar(max)) + '
        UNION ALL
        SELECT RCTE.level + 1 as Level, H2.Id, H2.ParentId, H2.text FROM ' + @TableName + ' H2
        INNER JOIN RecursiveCte RCTE ON H2.ParentId = RCTE.Id
    )
    select Id, Text, Level from RecursiveCte'

    EXEC sp_executesql @SQL;
END

编辑:

SQL fiddle 示例:http://sqlfiddle.com/#!3/d498b/22

关于sql-server - 如何使用存储过程在 SQL Server 2005 中使用 CTE 从分层数据中获取所有子项及其本身,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12858567/

相关文章:

mysql - 如何在 MySQL 程序中创建唯一的临时表?

sql-server - T-SQL 计算日期的重复次数

函数中的 Postgresql 公共(public)表达式表 (CTE)

sql - 您如何处理数据库表的配置管理?

sql-server - 如何从 SQL CLR 函数打印消息?

sql - EXEC 使用数据库

mysql - 使用 Case 语句创建存储过程

sql - 如何确定给定项目的字段值是否仅在增加?

sql - 返回 SQL Server 中的最大日期

sql-server - 根据搜索文本删除父子记录