2016-05-26 9 views
0

同じ機能を実現するために、現在のORACLEスクリプトを同等のMS SQL Serverバージョンに変換する際に問題があります。ORACLE階層のSTART WITH/CONNECT BY PRIORをSQL Server CTEに変換

私が行ったすべての研究は、唯一の解決策としてCTEを指摘しています。残っている唯一の問題は、シーケンスが正しくないことです。つまり、私は「階層」が正しく出てこないことを意味します。私はORDER BYを使用して結果セットを取得しようとしましたが、ROW_NUMBER()などを試しましたが、これらのアプローチのどれも非常にうまくいきません。私は、主な問題は、スクリプトがOracleスクリプトと同じ方法でレベルを上下に解析していないことです.CTEが完了した後、それを「修正」しようとすると、深いところに私を掘り下げています。

以下に2つのスクリプトを示します。

現在のOracle SQL SCRIPT VERSION(完璧に動作します)

SELECT lpad('-',2*(level-2), '-') || l.lcname descr, r.lrlocuri1 id, l.lciswithin, l.lctype, 1 lcisactive, l.lcvalidto 
    FROM tslocrel r, tslocation l WHERE l.uri=r.lrlocuri1 
    AND level>1 AND level<6 
    AND lctype=1 AND lcvalidto<'2' 
START WITH lrlocuri1=4485 CONNECT BY PRIOR lrlocuri1 = lrlocuri2 

MY MS SQL ServerのバージョンWIPの試み(SQL 2012 TARGET版です)

WITH locationCTE (lcname, lrlocuri1, lciswithin, lctype, lcisactive, lcvalidto, level) AS (

    SELECT l.lcname, r.lrlocuri1, l.lciswithin, l.lctype, 1 AS lcisactive, l.lcvalidto, 1 AS level 
    FROM tslocrel r 
    INNER JOIN tslocation l ON r.lrlocuri1 = l.uri 
    AND r.lrlocuri1=4485 

    UNION ALL 

    SELECT l.lcname, r.lrlocuri1, l.lciswithin, l.lctype, 1 AS lcisactive, l.lcvalidto, cte.level + 1 AS level 
    FROM tslocrel r 
    INNER JOIN tslocation l ON r.lrlocuri1 = l.uri 
    INNER JOIN locationCTE cte ON cte.lrlocuri1 = r.lrlocuri2 

) 

SELECT RIGHT(REPLICATE('-', 2*(level-2)) + LEFT('-', 2*(level-2)), 2*(level-2)) + lcname AS descr, lrlocuri1 id, lciswithin, lctype, lcisactive, 
lcvalidto 
FROM locationCTE 
WHERE level>1 AND level<6 
AND lctype=1 AND lcvalidto<'2' 

私は他のいくつかの試みを試みていると、基本的には同じ結果に戻ります。 これらのクエリはTRIMデータベース上で実行され、lrlocuri1とlrlocuri2を介して下をナビゲートすることによって 'Locations'の階層をリストすることになっています。定義上

General Manager 
    -Corporate Support 
    --Customer Service 
     --Xxxxxxx 
     --Xxxxxxx 
     (etc) 
    --Finance 
     --Xxxxx 
    -Environment and Planning 
    --Xxxxx 
    --Xxxxx 
    -Xxxxxxxxxxxx 
    --Xxxxx 
    --XXxxx 

など

+0

Oracleの経験がないSQL Serverのエキスパートが役立つように、SQL Serverで達成しようとしていることを説明できますか?あなたの現在のクエリの結果に何が間違っていますか? –

答えて

0

Oracleは、深さ優先順に階層的なデータセットを返します。したがって、ここでの注文は正しいです(例:https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm)。

一方、SqlServerにはこの結果セットの順序はありません。自分でデータ行を注文する必要があります。私の解決策は、データが選択された後にソートする階層的なパス値を各行ごとに構築することです。 Controlling the sibling order under recursive CTE?(欄を見てくださいパスを):あなたは、各行のid値を持っている場合は、ここでは、この

parent-id/child-id 

のようなものは、それの良い例です。

SQLServerのための他の解決策がありますが、主にそれより新しいバージョンのものについては、私は非常に興味があります。