SQL Server: How to limit CTE recursion to rows just recursivly added?

前端 未结 8 1066
北海茫月
北海茫月 2020-12-08 23:12

Simpler Example

Let\'s try a simpler example, so people can wrap their heads around the concepts, and have a practical example that you can copy&paste into SQL

8条回答
  •  醉梦人生
    2020-12-08 23:48

    The issue is with the Sql Server default recursion limit (100). If you try your example at the top with the anchor restriction removed (also added Order By):

    WITH NodeChildren AS
    (
       --initialization
       SELECT ParentNodeID, NodeID, 1 AS GenerationsRemoved
       FROM Nodes
    
       UNION ALL
    
       --recursive execution
       SELECT P.ParentNodeID, N.NodeID, P.GenerationsRemoved + 1
       FROM NodeChildren AS P
          inner JOIN Nodes AS N
          ON P.NodeID = N.ParentNodeID
    )
    SELECT ParentNodeID, NodeID, GenerationsRemoved
    FROM NodeChildren
    ORDER BY ParentNodeID ASC
    

    This produces the desired results. The problem you aare facing is with a larger number of rows you will recirse over 100 times which is a default limit. This can be changed by adding option (max recursion x) after your query, where x is a number between 1 and 32767. x can also be set to 0 which sets no limit however could very quickly have a very detrimental impact on your server performance. Clearly as the number of rows in Nodes increases, the number of recursions will can rise very quickly and I would avoid this approach unless there was a known upper limit on the rows in the table. For completeness, the final query should look like:

     WITH NodeChildren AS
        (
           --initialization
           SELECT ParentNodeID, NodeID, 1 AS GenerationsRemoved
           FROM Nodes
    
           UNION ALL
    
           --recursive execution
           SELECT P.ParentNodeID, N.NodeID, P.GenerationsRemoved + 1
           FROM NodeChildren AS P
              inner JOIN Nodes AS N
              ON P.NodeID = N.ParentNodeID
        )
        SELECT * 
        FROM NodeChildren
        ORDER BY ParentNodeID
        OPTION (MAXRECURSION 32767)
    

    Where 32767 could be adjusted downwards to fit your scenario

提交回复
热议问题