March 12, 2004 at 7:13 am
I need to write a sproc/udf (doesn't matter which) that will recursively retrieve records from a combination of two tables. Table A contains records that identify a user and organization(s) they have permission to access. However, table B contains a parent-child relationship for organizations. If someone in table A has permission to an organization that has children in table B, they also inherit permission to the child organizations. Here's some sample data.
TABLE A
-------
USER ORG
TOM 1
TOM 7
SAM 5
AL 3
AL 8
MIKE 7
TABLE B
-------
ORG PARENT
1 NULL
2 1
3 1
4 2
5 2
6 3
7 NULL
8 7
The results for TOM would be: "1, 2, 3, 4, 5, 6, 7, 8" since TOM has permissions to the "root" level orgs 1 and 7 plus all their children and their grandchildren. NOTE - the recursion may be more than three levels in the real-world.
The results for SAM would be: "5" since 5 has no children.
The results for AL would be: "3, 6, 8"
The results for MIKE would be: "7, 8"
Note that I'd like the results in a table/recordset versus a comma-delimited string to I can work with them using an ADO recordset.
Any thoughts? TIA... Steve
March 12, 2004 at 9:26 am
This is an offshoot of the solution suggested in BOL under the "hierarchical information" heading....
SET NOCOUNT ON
CREATE TABLE #TabA(Name Varchar(10),ID int)
CREATE TABLE #TabB(ChildID int,ParentID int)
CREATE TABLE #Stack(ID int,Level int)
CREATE TABLE #Results(ParentName Varchar(10),ParentID int,ChildID int)
INSERT #TabA(Name,ID)
SELECT 'Tom',1
UNION ALL
SELECT 'Tom',7
UNION ALL
SELECT 'Sam',5
UNION ALL
SELECT 'Al',3
UNION ALL
SELECT 'Al',8
UNION ALL
SELECT 'Mike',7
Insert #TabB(ChildID,ParentID)
SELECT 1,NULL
UNION ALL
SELECT 2,1
UNION ALL
SELECT 3,1
UNION ALL
SELECT 4,2
UNION ALL
SELECT 5,2
UNION ALL
SELECT 6,3
UNION ALL
SELECT 7,NULL
UNION ALL
SELECT 8,7
--SELECT * FROM #TabA
--SELECT * FROM #TabB
Declare @ID int
Declare @CurrID int
Declare @Level int
Declare @Name Varchar(10)
SET @Name = 'Tom'
DECLARE Name_CUR CURSOR FOR
SELECT [ID] FROM #TabA WHERE [Name] = @Name
FOR READ ONLY
OPEN Name_CUR
FETCH NEXT FROM Name_CUR INTO @ID
WHILE @@FETCH_STATUS = 0
BEGIN
SET @CurrID = @ID
INSERT #Stack([ID],[Level]) SELECT @CurrID,1
SET @Level = 1
WHILE @Level > 0
BEGIN
IF EXISTS(Select 1 FROM #Stack WHERE Level = @Level)
BEGIN
SELECT @CurrID = [ID] FROM #Stack WHERE [Level] = @Level
INSERT #Results(ParentName,ParentID,ChildID)
SELECT @Name,@ID,@CurrID
DELETE #Stack WHERE [Level] = @Level and [ID] = @CurrID
INSERT #Stack([ID],[Level])
SELECT ChildID,@Level+1 FROM #TabB WHERE ParentID = @CurrID
IF @@ROWCOUNT > 0
SET @Level = @Level + 1
END
ELSE
SET @Level = @Level - 1
END
FETCH NEXT FROM Name_CUR INTO @ID
END
CLOSE Name_CUR
DEALLOCATE Name_CUR
SELECT * FROM #Results ORDER BY ChildID
DROP TABLE #Stack
DROP TABLE #TabA
DROP TABLE #TabB
DROP TABLE #Results
SET NOCOUNT OFF
HTH
Temp tables...cursors...while loops....
Viewing 2 posts - 1 through 1 (of 1 total)
You must be logged in to reply to this topic. Login to reply