Technical Article

Find circular references in single table

,

The objective is to find circular references in a single table related to itself. The script deals with a sample table Skills that have a SkilGUID (primary key) field and a SkilParentGUID field which is a foreign key to the record's parent from the same table. The number of levels in the hierarchy is not limited. Of course, the highest object in a hierarchy will have NULL in ParentGUID field. Here the datatype for GUIDs is uniqueidentifier but it may as well be an int or whatever.

The script is rather straightforward and simple - it just returns the GUIDs engaged in circular references. Of course it may be enhanced in many possible ways.

SET NOCOUNT ON

DECLARE 
@BaseGUID uniqueidentifier,
@NextGUID uniqueidentifier,
@ParentGUID uniqueidentifier

CREATE TABLE #Temp 
(GUID uniqueidentifier)
CREATE TABLE #CircularGUIDS 
(CircGUID uniqueidentifier)

DECLARE TCursor CURSOR FAST_FORWARD LOCAL FOR
SELECT SkilGUID FROM Skills WHERE SkilGUID IS NOT NULL
OPEN TCursor

FETCH NEXT FROM TCursor INTO @BaseGUID
WHILE @@FETCH_STATUS = 0
BEGIN
TRUNCATE TABLE #Temp

SELECT @ParentGUID = SkilParentGUID FROM Skills WHERE SkilGUID = @BaseGUID
INSERT INTO #Temp (GUID) VALUES (@ParentGUID)
SET @NextGUID = @ParentGUID

NextIteration:
SELECT @ParentGUID = SkilParentGUID FROM Skills WHERE SkilGUID = @NextGUID
IF @ParentGUID NOT IN (SELECT GUID FROM #Temp) AND @ParentGUID IS NOT NULL
BEGIN
SET @NextGUID = @ParentGUID
INSERT INTO #Temp (GUID) VALUES (@ParentGUID)
GOTO NextIteration
END

IF @ParentGUID IN (SELECT GUID FROM #Temp)
BEGIN
INSERT INTO #CircularGUIDS (CircGUID) VALUES (@ParentGUID)
END

 FETCH NEXT FROM TCursor INTO @BaseGUID

END

CLOSE TCursor
DEALLOCATE TCursor

SELECT * FROM #CircularGUIDS

DROP TABLE #Temp
DROP TABLE #CircularGUIDS

Rate

3.67 (3)

You rated this post out of 5. Change rating

Share

Share

Rate

3.67 (3)

You rated this post out of 5. Change rating