【问题标题】:Loop never ends in SQL Server using While Exists使用 While Exists 在 SQL Server 中循环永远不会结束
【发布时间】:2016-10-27 05:33:46
【问题描述】:
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

【问题讨论】:

  • Daniel:请在评论中保持建设性。我的猜测是 abhi234u 不明白如何缩进代码.. 要添加您的代码,您需要在应该添加为代码 sn-ps 的文本之前有 4 个空格
  • 问题吗?或者这是一份关于您当前开发工作状态的报告?如果(隐含的)问题是“我为什么要观察这种行为?”,最可能的解释是 ColDepth IS NULL 中的行永远不会(也永远不会)被更新。例如,如果 Col 中有一行 (ParentId, Depth) 元组值为 (NULL,NULL),则该行将不受 UPDATE 语句的影响。
  • 之前有一个问题,但他已经将代码添加为图像,在我指示如何将文本添加为​​代码之后,我认为在编辑中删除了前一个问题。他还在问题中写道,查询给出了正确的输出,所以我认为 BEGIN 和 END 标签会指示代码知道查询代码的哪一部分应该受到 WHILE 循环的影响。这有点猜测,因为我们不知道相关代码后面是否有代码
  • 可能是父标识符之一为空?如果是,您的联接将不会评估为 true,因此永远不会更新该行的深度。

标签: sql sql-server while-loop


【解决方案1】:

您似乎正在尝试执行递归查询,而执行此操作的标准方法是使用 CTE:

;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

有关 CTE 的更多信息,您可以查看this technet link

【讨论】:

  • Kateract,我尝试了您的代码,但出现以下错误。递归查询“rec”的“LINEAGE”列中的锚点和递归部分之间的类型不匹配。
  • 尝试上述更改,使用 Cast 而不是 Str。
  • Kateract,没有行受 sql 影响。谢谢
  • 如果您使用 Select 而不是 Update,数据是否会返回?一次只能使用一个,CTE 只能用于下一条语句。
  • 数据未在选择中返回。谢谢
猜你喜欢
  • 2011-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多