CTE Query throws Recursion Exhausted error

跟風遠走 提交于 2019-12-12 04:40:01

问题


The following CTE Query throws "The statement terminated. The maximum recursion 100 has been exhausted before statement completion."

WITH MyCTE
AS (
SELECT o.organizationid,
        organization AS organization 
FROM organization o
    INNER JOIN store s ON s.organizationid = o.organizationid
UNION ALL
SELECT store.storeid,
            CAST(storeNAme AS NVARCHAR(50)) AS storeNAme 
FROM store
    INNER JOIN MyCTE ON store.organizationid = MyCTE.organizationid)

    SELECT DISTINCT
            Organization
    FROM MyCTE

when executing the subquery before and after the union all, the followig result is gained.

Anchor query:- SELECT o.organizationid, organization AS organization FROM organization o INNER JOIN store s ON s.organizationid = o.organizationid Result:-

organizationid    |organization
--------------------------------
3                 | Org1

query after union all:-

SELECT store.storeid, CAST(storeNAme AS NVARCHAR(50)) AS storeNAme FROM store

Result:-

StoreId           |StoreName
--------------------------------
3                 | Warehouse1

May I know the reason why ?


回答1:


Specify the maxrecursion option at the end of the query:

...
from MyCTE
option (maxrecursion 0)

That allows you to specify how often the CTE can recurse before generating an error. Maxrecursion 0 allows infinite recursion.




回答2:


When you are running recursive query, you allow a query to call itself. It doesn't matter how many rows query returns, but how many times a query will call itself. Therefore there is a risk it might go into infinite loop while. SQL Server in order to prevent this situation from happening have a setting which will determine how many recursions are allowed. Default value for this setting is 100 - therefore you will get this message when your query exceeds 100 recursions (self calls).

You can override this setting by adding OPTION (MAXRECURSION nn) at the end of query. When nn is new maximum.

You can also remove protection completely by setting this value to 0 - it will looks like this then: OPTION (MAXRECURSION 0) however this is not recommended since when running it will keep consuming resources.


OP asked for suggestion how to avoid potential infinite loop, and create exit criteria for recursion.

As far as I can see you are trying to build data hierarchy. You might consider introducing additional column with hierarchy level and stop at some level (I choose 10 in example):

WITH MyCTE
     AS (
     SELECT o.organizationid,
            organization AS organization,
          1 lvl
     FROM organization o
          INNER JOIN store s ON s.organizationid = o.organizationid
     UNION ALL
     SELECT store.storeid,
            CAST(storeNAme AS NVARCHAR(50)) AS storeNAme,
          lvl+1
     FROM store
          INNER JOIN MyCTE ON store.organizationid = MyCTE.organizationid
     WHERE lvl<10
)
SELECT DISTINCT
    Organization
FROM MyCTE


来源:https://stackoverflow.com/questions/45408509/cte-query-throws-recursion-exhausted-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!