2016-04-05 84 views
0
with closure (obj_1, obj_2) as (
SELECT distinct t.obj_1, t.obj_2 
    FROM temp4 t 
UNION ALL 
SELECT c.obj_1, t.obj_2 
    FROM closure c, temp4 t 
    WHERE c.obj_2=t.obj_1) 
SELECT * FROM closure 

由於數據中有循環,有沒有一種方法可以在此語句中添加停止條件,所以如果行已經存在於閉包中,我希望它停止該行的遞歸。如何把遞歸sql的停止條件?

+0

你需要保持跟蹤訪問的對象並使用該信息停止處理。 –

+0

@GordonLinoff你可以參考一個例子或文件解釋這可能嗎?我完全不熟悉這一點,很高興看到我可以嘗試的東西。 – Nataly

+0

。 。我已經在SQL Server中完成了這項工作,但不是在DB2中完成的。一個想法是將對象ID保留在一個字符串(和其他列)中,並檢查ID是否未被使用。 –

回答

0

這個例子限制了環路,100 - 我認爲你的想法:

with closure (obj_1, obj_2, counter) as (
SELECT distinct t.obj_1, t.obj_2 , 1 
    FROM temp4 t 
UNION ALL 
SELECT c.obj_1, t.obj_2, counter + 1 
    FROM closure c, temp4 t 
    WHERE c.obj_2=t.obj_1 
    AND counter <= 100) 
SELECT * FROM closure 
+0

謝謝,這有助於無限循環問題,但我需要我的停止條件是:如果閉包已經包含(obj_1,obj_2)然後不要停下來。我需要這個來防止週期。 – Nataly

+0

更好,是否有一種方法可以指定UNION ALL的第二部分,以便不包含它正在遞歸的當前行以防止循環? – Nataly

0

最簡單的方法是建立一個查詢幫手,像這樣

with closure (obj_1, obj_2) as (
SELECT distinct t.obj_1, t.obj_2,convert(varchar(30),t.obj_1)+';' as treePath 
    FROM temp4 t 
UNION ALL 
SELECT c.obj_1, t.obj_2 convert(varchar(30),t.obj_2)+';' as treePath 
    FROM closure c, temp4 t 
    WHERE c.obj_2=t.obj_1 
and charindex(';' + convert(varchar(30),t.obj_2)+';',treepath,1)=0 
SELECT * FROM closure