循环永远不会在SQL Server中使用While Exists结束

循环永远不会在SQL Server中使用While Exists结束,sql,sql-server,while-loop,Sql,Sql Server,While Loop,看起来您正在尝试执行递归查询,标准方法是使用CTE: While Exists (Select * From Col Where Depth Is Null) Update T Set T.Depth = P.Depth + 1, T.Lineage = P.Lineage + LTrim(Str(T.ParentId, 6, 0)) + '/' From Col T Join Col P On T.ParentId = P.Id Wher

看起来您正在尝试执行递归查询,标准方法是使用CTE:

While Exists (Select * From Col Where Depth Is Null)
    Update T
    Set T.Depth = P.Depth + 1,
        T.Lineage = P.Lineage + LTrim(Str(T.ParentId, 6, 0)) + '/'
    From Col T
    Join Col P On T.ParentId = P.Id
    Where
        P.Depth >= 0
        And P.Lineage Is Not Null
        And T.Depth Is Null

有关CTE的更多信息,请查看。

Daniel:请在评论中提出建设性意见。我猜abhi234u不懂如何缩进代码。。要添加代码,在应该作为代码段添加的文本之前需要4个空格有问题吗?或者这是您当前开发工作状态的报告?如果隐含的问题是我为什么要观察这种行为,最有可能的解释是Col中有深度为NULL的行,这些行永远不会更新,也永远不会更新。例如,如果Col中有一行的ParentId、Depth tuple值为NULL、NULL,那么该行不会受到UPDATE语句的影响。前面有一个问题,但他将代码添加为图像,在我指示如何将文本添加为代码后,我想前一个问题在编辑中被删除了。他还在问题中写道,查询给出了正确的输出,因此我认为BEGIN和END标记将指示代码知道查询代码的哪一部分应该受到WHILE循环的影响。这有点像猜测,因为我们不知道在问题代码后面是否有代码,是否有一个父标识符是空的?如果是这样,则您的联接将不会计算为true,因此将永远不会更新该行的深度。Kateract,我尝试了您的代码,但出现以下错误。递归查询rec的列沿袭中的锚点和递归部分之间的类型不匹配。请尝试进行上述更改,使用Cast而不是Str.Kateract,sql不会影响任何行。谢谢如果您使用选择而不是更新,数据是否会返回?一次只能使用一条语句,CTE只能用于下一条语句。select语句中不会返回数据。谢谢
;WITH rec AS(
SELECT c.Id, c.Depth, CAST(c.Id AS varchar(MAX) + '/' AS Lineage
    FROM Col c
    WHERE c.ParentId IS NULL
    UNION ALL
    SELECT c1.Id, rec.Depth + 1, rec.Lineage + CAST(c1.id as varchar(10)) + '/'
    FROM rec
    INNER JOIN Col c1 on rec.Id = c1.ParentId
    WHERE rec.Depth < 100 --Limit the recursion, set this to what is appropriate for your data
)
--SELECT * FROM rec --Use this first to see if the data is correct, then:
UPDATE T
SET T.Depth = r.Depth, T.Lineage = r.Lineage
FROM Col T
INNER JOIN rec r ON T.Id = r.Id