Reputation: 694
I have a recursive CTE-query like this:
;WITH cte
AS ( SELECT e.entryID ,
e.bOpen ,
e.nextEntryID ,
e.entryID AS OriginalentryID
FROM entries e
WHERE e.bOpen = 1
AND e.nextEntryID IS NOT NULL
UNION ALL
SELECT e.entryID ,
e.bOpen ,
e.nextEntryID ,
c.OriginalentryID
FROM cte c
INNER JOIN entries e ON e.entryID = c.nextEntryID
)
SELECT c.entryID ,
c.OriginalentryID
FROM cte c
WHERE bOpen = 0;
Would there be any way to realise this without CTE
(i.e. for SQL Server 2000)?
Any hints/ideas are appreciated.
Upvotes: 2
Views: 1121
Reputation: 6713
For SQL 2000, you can create a table-function that mimics your CTE expression, using a temporary table and a WHILE
loop to load it.
The main drawback is that you won't benefit from applying WHERE
constraints before returning from the function, but it works if the hierarchy table is small. To lessen the amount of data read before the WHERE
clauses apply, you can pass parameters to filter (see comment on code):
CREATE FUNCTION dbo.FnGetEntriesByRoot (@rootId AS BIGINT)
RETURNS @result TABLE (
entryID BIGINT PRIMARY KEY,
bOpen BIT,
nextEntryID BIGINT,
OriginalentryID BIGINT
)
AS BEGIN
-- insert the "root" element
INSERT @result(entryID, bOpen, nextEntryID, OriginalentryID)
SELECT e.entryID, e.bOpen, e.nextEntryID, e.entryID
FROM entries e
WHERE e.bOpen = 1
AND (e.entryID = @rootId OR @rootId IS NULL) -- (1) filter condition!
AND e.nextEntryID IS NOT NULL;
-- while new items are found, insert into the result table
WHILE (@@ROWCOUNT > 0) BEGIN
INSERT @result(entryID, bOpen, nextEntryID, OriginalentryID)
SELECT e.entryID, e.bOpen, e.nextEntryID, c.OriginalentryID
FROM @result c
JOIN entries e ON (e.entryID = c.nextEntryID)
WHERE e.entryID NOT IN (SELECT entryID FROM @result)
END
RETURN;
END;
SELECT c.entryID, c.OriginalentryID
FROM dbo.FnGetEntriesByRoot(NULL) c
WHERE c.bOpen = 0;
Upvotes: 2