I have a typical set of employee and the corresponding manager as most recursive CTE tutorials use. I took it from Uri Dimant's answer in tutorial.
Unlike depth-first search, my goal is to input an employee ID, and the query returns the list of managers up to the root.
So, I tweak the JOIN statement to join manager id from CTE to employee ID. It should get the manager's names for a certain employee.
It results an error:
The statement terminated. The maximum recursion 100 has been exhausted before statement completion.
I thought that when the recursion reaches the highest rank of the manager, it would return an empty resultset indicating the end of the recursion.
I want to understand how the SQL engine knows when to stop. and how to make this query works as I expected.
thank you
IF OBJECT_ID('Employees') IS NULL
BEGIN
CREATE TABLE Employees
(
empid int NOT NULL,
mgrid int NULL,
empname nvarchar(25) NOT NULL,
salary money NOT NULL,
CONSTRAINT PK_Employees PRIMARY KEY(empid),
CONSTRAINT FK_Employees_mgrid_empid
FOREIGN KEY(mgrid)
REFERENCES Employees(empid)
)
CREATE INDEX idx_nci_mgrid ON Employees(mgrid)
SET NOCOUNT ON
INSERT INTO Employees VALUES(1 , NULL, 'Nancy' , $10000.00)
INSERT INTO Employees VALUES(2 , 1 , 'Andrew' , $5000.00)
INSERT INTO Employees VALUES(3 , 1 , 'Janet' , $5000.00)
INSERT INTO Employees VALUES(4 , 1 , 'Margaret', $5000.00)
INSERT INTO Employees VALUES(5 , 2 , 'Steven' , $2500.00)
INSERT INTO Employees VALUES(6 , 2 , 'Michael' , $2500.00)
INSERT INTO Employees VALUES(7 , 3 , 'Robert' , $2500.00)
INSERT INTO Employees VALUES(8 , 3 , 'Laura' , $2500.00)
INSERT INTO Employees VALUES(9 , 3 , 'Ann' , $2500.00)
INSERT INTO Employees VALUES(10, 4 , 'Ina' , $2500.00)
INSERT INTO Employees VALUES(11, 7 , 'David' , $2000.00)
INSERT INTO Employees VALUES(12, 7 , 'Ron' , $2000.00)
INSERT INTO Employees VALUES(13, 7 , 'Dan' , $2000.00)
INSERT INTO Employees VALUES(14, 11 , 'James' , $1500.00)
END
GO
WITH EmpCTE
AS
(
-- Anchor Member (AM)
SELECT
empid,
empname,
mgrid,
0 AS level -- <------------------- SET LVL START FROM 0
FROM Employees
WHERE EMPID = 7
UNION ALL
-- Recursive Member (RM)
SELECT
e.empid,
e.empname,
e.mgrid,
e.level+1 -- <------------------- INCREMENT LVL
manager id
FROM Employees AS m
JOIN EmpCTE AS e -- <------------------- RECURSIVELY CALL EmpCTE
ON e.mgrid = m.empid
)
SELECT * FROM EmpCTE
You've managed to create an infinite loop. You can stick in a filter against
levelto debug these:(also after removing the
manager id)This is because you are projecting the columns from
EmpCTE as erather thanEmployees as m, so you're just getting the same data again and again (plus the level being increased).