Değiştiremediğim aşağıdaki şemaya sahibim (isimler değiştirildi):
CREATE TABLE MyTable (
Id INT NOT NULL PRIMARY KEY,
ParentId INT NOT NULL
);
ALTER TABLE MyTable ADD FOREIGN KEY (ParentId) REFERENCES MyTable(Id);
Yani, her kayıt başka bir kaydın çocuğudur. Bir kaydın ParentId
değeri ona eşitse Id
, kayıt bir kök düğümü olarak kabul edilir.
Tüm döngüsel referansları bulacak sorguyu çalıştırmak istiyorum. Örneğin, verilerle
INSERT INTO MyTable (Id, ParentId) VALUES
(0, 0),
(1, 0),
(2, 4),
(3, 2),
(4, 3);
sorgu dönmelidir
Id | Cycle
2 | 2 < 4 < 3 < 2
3 | 3 < 2 < 4 < 3
4 | 4 < 3 < 2 < 4
Aşağıdaki sorguyu SQL Server 2008 R2 için yazdım ve bu sorgunun geliştirilip geliştirilemeyeceğini merak ediyorum:
IF OBJECT_ID(N'tempdb..#Results') IS NOT NULL DROP TABLE #Results;
CREATE TABLE #Results (Id INT, HasParentalCycle BIT, Cycle VARCHAR(MAX));
DECLARE @i INT,
@j INT,
@flag BIT,
@isRoot BIT,
@ids VARCHAR(MAX);
DECLARE MyCursor CURSOR FAST_FORWARD FOR
SELECT Id
FROM MyTable;
OPEN MyCursor;
FETCH NEXT FROM MyCursor INTO @i;
WHILE @@FETCH_STATUS = 0
BEGIN
IF OBJECT_ID(N'tempdb..#Parents') IS NOT NULL DROP TABLE #Parents;
CREATE TABLE #Parents (Id INT);
SET @ids = NULL;
SET @isRoot = 0;
SET @flag = 0;
SET @j = @i;
INSERT INTO #Parents (Id) VALUES (@j);
WHILE (1=1)
BEGIN
SELECT
@j = ParentId,
@isRoot = CASE WHEN ParentId = Id THEN 1 ELSE 0 END
FROM MyTable
WHERE Id = @j;
IF (@isRoot = 1)
BEGIN
SET @flag = 0;
BREAK;
END
IF EXISTS (SELECT 1 FROM #Parents WHERE Id = @j)
BEGIN
INSERT INTO #Parents (Id) VALUES (@j);
SET @flag = 1;
SELECT @ids = COALESCE(@ids + ' < ', '') + CAST(Id AS VARCHAR) FROM #Parents;
BREAK;
END
ELSE
BEGIN
INSERT INTO #Parents (Id) VALUES (@j);
END
END
INSERT INTO #Results (Id, HasParentalCycle, Cycle) VALUES (@i, @flag, @ids);
FETCH NEXT FROM MyCursor INTO @i;
END
CLOSE MyCursor;
DEALLOCATE MyCursor;
SELECT Id, Cycle
FROM #Results
WHERE HasParentalCycle = 1;
Hayır, 0 bir kök düğümdür, çünkü ona
—
cubetwo1729
ParentId
eşittir Id
, bu nedenle bu senaryo için bir döngü değildir.
0 > 0
Bir döngü düşünülmemelidir?