1. 程式人生 > 其它 >SQLServer CTE 遞迴查詢限制遞迴級數(完成執行語句前已用完最大遞迴)

SQLServer CTE 遞迴查詢限制遞迴級數(完成執行語句前已用完最大遞迴)

SQLServer CTE 遞迴查詢限制遞迴級數(完成執行語句前已用完最大遞迴)

介紹

如果遞迴 CTE 組合不正確,可能會導致無限迴圈。 例如,如果遞迴成員查詢定義對父列和子列返回相同的值,則會造成無限迴圈。 可以使用 MAXRECURSION 來限制特定語句所允許的遞迴級數,以防止出現無限迴圈。 這樣就能夠在解決產生迴圈的程式碼問題之前控制語句的執行。

MAXRECURSION <integer_value>

指定該查詢允許的最大遞迴數。 <integer_value> 是介於 0 至 32,767 之間的非負整數。 如果指定 0,則沒有限制。 如果未指定此選項,伺服器的預設限制為 100。

如果在查詢執行期間達到指定或預設的 MAXRECURSION 數量限制,查詢結束並返回錯誤。

由於此錯誤,該語句的所有結果都被回滾。 如果該語句為 SELECT 語句,則可能會返回部分結果或不返回結果。 所返回的任何部分結果都可能無法包括超過指定最大遞迴級別的遞迴級別上的所有行。

參考文件

遞迴公用表表達式的準則

MAXRECURSION

示例

建立測試資料

create table #ceshi(id int, pid int, mc varchar(20))
insert into #ceshi
  values(1, 0, '1級科目_1'), (2, 0, '1級科目_2'),
        (3, 1, '2級科目_1'), (4, 2, '2級科目_2'), 
		(5, 3, '3級科目_1'), (6, 4, '3級科目_2'), 
		(7, 5, '4級科目_1'), (8, 6, '4級科目_2') 

設定只遞迴查詢2次(預設值為 100)

WITH 
  cte AS
  (Select *, id * 10 sxh from #ceshi where pid = 0
   union all
   Select A.*, sxh + 1 from #ceshi A INNER JOIN cte B ON A.pid = B.id
)
select * from cte order by sxh OPTION (MAXRECURSION 2)

錯誤提示

訊息 530,級別 16,狀態 1,第 1 行
語句被終止。完成執行語句前已用完最大遞迴 2。

修改為不限制遞迴查詢次數

WITH 
  cte AS
  (Select *, id * 10 sxh from #ceshi where pid = 0
   union all
   Select A.*, sxh + 1 from #ceshi A INNER JOIN cte B ON A.pid = B.id
)
select * from cte order by sxh OPTION (MAXRECURSION 0)

查詢結果

id pid mc sxh
1 0 1級科目_1 10
3 1 2級科目_1 11
5 3 3級科目_1 12
7 5 4級科目_1 13
2 0 1級科目_2 20
4 2 2級科目_2 21
6 4 3級科目_2 22
8 6 4級科目_2 23