我有一个复杂的存储过程MyStoredProc
(我无法更改,这个例子大大简化了),它获取了一个Id并返回了一个ID和标题列表,类似于:
输入= 100
Id Title HasChilds
----------------------------
101 CategoryA 0
102 CategoryB 0
103 CategoryC 1
104 CategoryD 0
输入= 103
Id Title HasChilds
----------------------------
105 SubCatA 0
106 SubCatB 1
107 SubCatC 0
输入= 106
Id Title HasChilds
----------------------------
108 SubA 0
109 SubB 0
我的目标是编写一个查询来将其整理成一行,并将分支放在括号中:
CategoryA, CategoryB, CategoryC (SubCatA, SubCatB (SubA, SubB), SubCatC), CategoryD
鉴于深度不超过4-5级,我该如何在T-SQL中执行此操作?
我尝试将MyStoredProc
输出转储到临时表
INSERT INTO #tmpTable
EXEC MyStoredProc @_Id = 100
然后用光标遍历它并将分支附加到同一个临时表。那就是我被困住的地方。我不知道如何将ParentId
附加到临时表行,以便我可以使用从最后一行的光标到第一个将分支字符串附加到父行字符串。也许这完全是错误的做法。
答案 0 :(得分:1)
这应该这样做(注意这里的一半脚本是设置与你的例子匹配的数据):
CREATE PROCEDURE MyStoredProc (
@Id INT)
AS
BEGIN
IF @Id = 100
BEGIN
SELECT 101 AS Id, 'CategoryA' AS Title, 0 AS HasChilds
UNION ALL
SELECT 102 AS Id, 'CategoryB' AS Title, 0 AS HasChilds
UNION ALL
SELECT 103 AS Id, 'CategoryC' AS Title, 1 AS HasChilds
UNION ALL
SELECT 104 AS Id, 'CategoryD' AS Title, 0 AS HasChilds
END;
IF @Id = 103
BEGIN
SELECT 105 AS Id, 'SubCatA' AS Title, 0 AS HasChilds
UNION ALL
SELECT 106 AS Id, 'SubCatB' AS Title, 1 AS HasChilds
UNION ALL
SELECT 107 AS Id, 'SubCatC' AS Title, 0 AS HasChilds
END;
IF @Id = 106
BEGIN
SELECT 108 AS Id, 'SubA' AS Title, 0 AS HasChilds
UNION ALL
SELECT 109 AS Id, 'SubB' AS Title, 0 AS HasChilds
END;
END;
GO
CREATE PROCEDURE GetCategoryList(
@StartId INT,
@Result VARCHAR(2048) OUTPUT)
AS
BEGIN
DECLARE @tmpTable TABLE (
Id INT,
Title VARCHAR(50),
HasChilds INT);
INSERT INTO @tmpTable EXEC MyStoredProc @StartId;
DECLARE @Id INT = NULL;
SELECT TOP 1 @Id = Id FROM @tmpTable ORDER BY Id;
SELECT @Result = '';
WHILE @Id IS NOT NULL
BEGIN
DECLARE @Title VARCHAR(50);
DECLARE @HasChilds INT;
SELECT @Title = Title, @HasChilds = HasChilds FROM @tmpTable WHERE Id = @Id;
SELECT @Result = @Result + @Title;
IF @HasChilds = 0
BEGIN
SELECT @Result = @Result + ', ';
END;
ELSE
BEGIN
DECLARE @Append VARCHAR(2048);
EXEC GetCategoryList @Id, @Append OUTPUT;
SELECT @Result = @Result + ' (' + @Append + '), ';
END;
--Get the next id
DECLARE @LastId INT;
SELECT @LastId = @Id;
SELECT @Id = NULL;
SELECT TOP 1 @Id = Id FROM @tmpTable WHERE Id > @LastId ORDER BY Id;
END;
SELECT @Result = SUBSTRING(@Result, 1, LEN(@Result) - 1);
END;
GO
DECLARE @Result VARCHAR(2048);
EXEC GetCategoryList 100, @Result OUTPUT;
SELECT @Result;