2017-07-31 55 views
0

以下CTE查詢拋出「語句已終止,最大遞歸100在語句完成前已耗盡」。CTE查詢拋出遞歸用盡錯誤

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 

在union all之前和之後執行子查詢時,獲得followig結果。

錨查詢: - 選擇o.organizationid, 組織作爲組織 從組織爲O INNER JOIN店S於s.organizationid = o.organizationid 結果: -

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

後,聯盟所有查詢: -

SELECT store.storeid, CAST(STORENAME AS NVARCHAR(50))AS STORENAME FROM商店

結果: -

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

我可以知道原因?

回答

2

在查詢結束指定MAXRECURSION選項:

... 
from MyCTE 
option (maxrecursion 0) 

這允許您指定的CTE如何往往會產生錯誤之前遞歸。 Maxrecursion 0允許無限遞歸。

+0

1+從我和一些除了回答:按CTE支持默認的最大遞歸級別爲100,但CTE提供了一個通過MAXRECURSION提示改變它的選項。 MAXRECURSION提示值可以介於0到32,767之間。將它的值指定爲0意味着沒有限制。 – Anil

+0

@Raj我想知道爲什麼查詢進入最大遞歸時,個別查詢只返回一行作爲結果 – user2838738

0

當您運行遞歸查詢時,您允許查詢自行調用。查詢返回的行數並不重要,但查詢將自行調用多少次。因此,它有可能陷入無限循環的風險。 SQL Server爲了防止這種情況發生,有一個設置將決定允許多少次遞歸。此設置的默認值爲100 - 因此,當您的查詢超過100次遞歸(自我調用)時,您將收到此消息。

您可以通過在查詢結束時添加OPTION (MAXRECURSION nn)來覆蓋此設置。當nn是新的最大值。

您也可以通過將此值設置爲0來完全移除保護 - 它看起來像這樣:OPTION (MAXRECURSION 0)但是,這是不推薦的,因爲它在運行時會持續消耗資源。


OP詢問建議如何避免潛在的無限循環,並創建遞歸退出條件。

據我所見,您正在嘗試構建數據層次結構。你可能會考慮與層級引入額外的列,並在一定程度上阻止(我選擇10例中):

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 
+0

先給予子查詢的結果....其單個行從兩個子查詢返回....**爲什麼**查詢進入遞歸是我的問題 – user2838738

+0

檢查我更新的答案。無論你會得到多少行都無所謂 - 重要的是它會自己調用多少行。 –

+1

順便說一句,如果將MAXRECURSION設置爲0,我認爲查詢可能實際進入無限循環(取決於您的數據)。 –