2016-04-05 47 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では行っていません。 1つのアイデアは、オブジェクト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の2番目の部分に、サイクルを防ぐために再帰的に実行されている現在の行を含めない方法を指定できますか? – 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 
関連する問題