Максимальная рекурсия 100 была использована до завершения инструкции

I keep getting a max recursion error with this query.

At first I thought it was because a null was being returned and then it would try and match the null values causing the error however, I rewrote my query so nulls aren’t returned and the error still occurs.

What would be the best way to rewrite this function, so that the error will not occur

WITH EmployeeTree AS
(
    SELECT 
        EMP_SRC_ID_NR Id, USR_ACV_DIR_ID_TE Uuid, 
        CASE Employees.APV_MGR_EMP_ID 
           WHEN Null THEN '0' 
           ELSE Employees.APV_MGR_EMP_ID 
        END as  ApprovalManagerId 
    FROM 
        dbo.[tEmployees] as Employees WITH (NOLOCK)
    WHERE 
        APV_MGR_EMP_ID = @Id 
        and Employees.APV_MGR_EMP_ID is not null 
        and Employees.EMP_SRC_ID_NR is not null  

    UNION ALL

    SELECT 
        EMP_SRC_ID_NR Id, USR_ACV_DIR_ID_TE Uuid, 
        CASE Employees.UPS_ACP_EMP_NR 
           WHEN Null THEN '1' 
           ELSE Employees.UPS_ACP_EMP_NR 
        END as ApprovalManagerId 
    FROM 
        dbo.[tEmployees] as Employees WITH (NOLOCK)
    WHERE 
        UPS_ACP_EMP_NR = @Id 
        and Employees.APV_MGR_EMP_ID is not null 
        and Employees.EMP_SRC_ID_NR is not null  

    UNION ALL

    SELECT 
        Employees.EMP_SRC_ID_NR, Employees.USR_ACV_DIR_ID_TE, 
        CASE Employees.APV_MGR_EMP_ID 
            WHEN Null THEN '2' 
            ELSE Employees.APV_MGR_EMP_ID 
        END  
    FROM 
        dbo.[tEmployees] as Employees WITH (NOLOCK)
    JOIN 
        EmployeeTree ON Employees.APV_MGR_EMP_ID = EmployeeTree.Id 
    where  
        Employees.APV_MGR_EMP_ID is not null 
        and Employees.EMP_SRC_ID_NR is not null             
)
SELECT 
    Id AS [EmployeeId], 
    Uuid AS [EmployeeUuid], 
    ApprovalManagerId AS [ManagerId] 
FROM EmployeeTree        

«The maximum recursion 100 has been exhausted before statement completion» error showing in SQL Query

WITH DepartmentCTE AS
(   SELECT  ID, 
        DepartmentName, 
        RootID, 
        RecursionLevel = 1, 
        ParentRoot = CAST('None' AS NVARCHAR(max)),
        LastParentCatID = RootID,
        DisplayOrder
FROM    Department
UNION ALL
SELECT  cte.ID, 
        cte.DepartmentName,
        cte.RootID,
        cte.RecursionLevel + 1,
        ParentRoot = CASE WHEN cte.RecursionLevel = 1 THEN '' ELSE cte.ParentRoot + '>' END + c.DepartmentName,
        LastParentCatID = c.RootID,
        cte.DisplayOrder
FROM    DepartmentCTE cte
        INNER JOIN Department c
            ON c.ID = cte.RootID

), MaxRecursion AS
(   SELECT  ID, 
        DepartmentName, 
        RootID, 
        ParentRoot, 
        RowNum = ROW_NUMBER() OVER(PARTITION BY ID ORDER BY RecursionLevel DESC),
        DisplayOrder
FROM    DepartmentCTE
)
SELECT  ID, DepartmentName, RootID, ParentRoot
FROM    MaxRecursion 
WHERE   RowNum = 1;

One of the most benefit of CTE (Common Table Expressions) is that we can create recursive queries with them. In my previous posts I’ve discussed this topic with some good examples, link.

An incorrectly composed recursive CTE may cause an infinite loop. So recursive CTEs should be designed very carefully and the recursion level should be checked. To prevent it to run infinitely SQL Server’s default recursion level is set to 100. But you can change the level by using the MAXRECURSION option/hint. The recursion level ranges from 0 and 32,767.

If your CTEs recursion level crosses the limit then following error is thrown by SQL Server engine:
Msg 530, Level 16, State 1, Line 11
The statement terminated. The maximum recursion 100 has been exhausted before statement completion.

Let’s check this with an example discussed in MSDN TSQL forum, link:

DECLARE
	@startDate DATETIME,
	@endDate DATETIME

SET @startDate = '11/10/2011'
SET @endDate = '03/25/2012'

; WITH CTE AS (
	SELECT
		YEAR(@startDate) AS 'yr',
		MONTH(@startDate) AS 'mm',
		DATENAME(mm, @startDate) AS 'mon',
		DATEPART(d,@startDate) AS 'dd',
		@startDate 'new_date'
	UNION ALL
	SELECT
		YEAR(new_date) AS 'yr',
		MONTH(new_date) AS 'mm',
		DATENAME(mm, new_date) AS 'mon',
		DATEPART(d,@startDate) AS 'dd',
		DATEADD(d,1,new_date) 'new_date'
	FROM CTE
	WHERE new_date < @endDate
	)
SELECT yr AS 'Year', mon AS 'Month', count(dd) AS 'Days'
FROM CTE
GROUP BY mon, yr, mm
ORDER BY yr, mm
OPTION (MAXRECURSION 1000)
Output:-

Year	Month		Days
2011	November	22
2011	December	31
2012	January		31
2012	February	29
2012	March		24

Here, by applying “OPTION (MAXRECURSION 1000)”, we can set the recursion level, so that it does not go infinite.

Note: Restriction of recursive CTE is – “A view that contains a recursive CTE cannot be used to update data”.

More info on: http://msdn.microsoft.com/en-us/library/ms175972.aspx

Westnik76

0 / 0 / 0

Регистрация: 06.02.2015

Сообщений: 2

1

06.02.2015, 20:37. Показов 7117. Ответов 3

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

нужно найти потомков в дереве начиная с @P, вылезает еще ошибка » Msg 530, Level 16, State 1, Line 58
Выполнение инструкции прервано. Максимальная рекурсия 100 была использована до завершения инструкции»

SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Лицевые счета] ROW_ID INT IDENTITY(1,1) NOT NULL,
                         Счета  INT NOT NULL, --поле иерархии (связь на родительскую запись)
                         Номер INT NULL           -- номер лицевого счета
 
 
WITH Rec (Номер, ROW_ID, level)
AS 
   (SELECT Номер, ROW_ID, 0
   FROM dbo.[Лицевые счета] AS L
   WHERE ROW_ID =@P 
UNION ALL
   SELECT L.Номер, L.ROW_ID, Rec.level + 1
   FROM dbo.[Лицевые счета] AS L   INNER JOIN Rec
   ON  L.Счета = Rec.ROW_ID)
 
SELECT * FROM Rec;



0



Metall_Version

2148 / 1285 / 516

Регистрация: 04.03.2014

Сообщений: 4,092

07.02.2015, 10:44

2

Westnik76, так нету же условия выхода из рекурсии

к примеру ставим глубину рекурсии 10

SQL
1
2
3
4
5
6
7
8
9
10
WITH Rec (Номер, ROW_ID, level)
AS 
   (SELECT Номер, ROW_ID, 10
   FROM dbo.[Лицевые счета] AS L
   WHERE ROW_ID =@P 
UNION ALL
   SELECT L.Номер, L.ROW_ID, Rec.level - 1
   FROM dbo.[Лицевые счета] AS L   INNER JOIN Rec
     ON  L.Счета = Rec.ROW_ID)
   WHERE level > 0



1



3329 / 2034 / 727

Регистрация: 02.06.2013

Сообщений: 5,008

07.02.2015, 11:09

3

Лучший ответ Сообщение было отмечено Westnik76 как решение

Решение

Westnik76, ищите кольцевые ссылки в таблице.



1



0 / 0 / 0

Регистрация: 06.02.2015

Сообщений: 2

09.02.2015, 00:57

 [ТС]

4

накосячил при заполнении таблицы, спасибо за помощь



0



October 22 2010, 01:43

Однако!

SQL Server:

C:>sqlcmd
1> with tq as(
2>  select 1 as n
3>  union all
4>  select n+1 from tq where n<1000
5> )
6> select * from tq
7> go
n
-----------
Сообщение 530, уровень 16, состояние 1, сервер ДОМ, строка 1
Выполнение инструкции прервано. Максимальная рекурсия 100 была использована до завершения инструкции.

Postgres:

C:>psql -U postgres
psql (9.0beta3)
WARNING: Console code page (866) differs from Windows code page (1251)
         8-bit characters might not work correctly. See psql reference
         page "Notes for Windows users" for details.
Type "help" for help.

postgres=# with recursive tq as(
postgres(#  select 1 as n
postgres(#  union all
postgres(#  select n+1 from tq where n<1000
postgres(# )
postgres-# select * from tq;
  n
------
    1
    2
    3
...
  998
  999
 1000
(1000 rows)

Или даже так:

postgres=# with recursive tq as(
postgres(#  select 1 as n
postgres(#  union all
postgres(#  select n+1 from tq where n<1000000
postgres(# )
postgres-# select count(*) from tq;
  count
---------
 1000000
(1 row)

Понравилась статья? Поделить с друзьями:
  • Blue glide swix инструкция по применению
  • Video repair tool инструкция по применению
  • Сироп от кашля подорожник доктор тайсс инструкция
  • Как пить ригевидон инструкция по применению взрослым таблетки
  • Панкреатин лект инструкция по применению таблетки взрослым от чего помогает