2017-02-16 11 views
0

データを移行していますが、前にロールバックスクリプトを生成します。表中のx個の行数のOracle listaggグループ

重要な列は次のようになります。

id code 
----- ------- 
1234 121212 
1345 434343 
2345 121212 
    ... 

を私は252525にすべてのコード121212151515を変えていますが、何かがどこかうまくいかない場合、私は戻ってそれらを変更できるようにする必要があります。

私は、listaggを使用して、更新ステートメントのwhere節で使用できるIDのコンマ区切りリストを作成しました。これらの線に沿って何か:これは私のDEV-環境にいるかのように、小さなセットのために完璧に動作しますが、本番では、私は、文字列の長さ(ORA-01489)の限界に達し

select '... set code='||code||' where id in (' 
|| listagg(id,',') within group (order by id) 
|| ');' as RB_STMT 
from mytable 
where code in (121212,151515) 
group by code; 

だから私は何をできるようにしたいことは、X = 5のためのための結果はであろうように、コードに加えて、IDSのx数でグループにある:

RB_STMT 
------------ 
...set code=121212 where id in (1234,1235,1236,1237,1238); 
...set code=121212 where id in (1239,2111,2112,2123,2124); 
...set code=121212 where id in (2125,2126,2136); 
...set code=151515 where id in (1456,2345,2468,2469,2470); 
etc. 

(Iが使用します実際にはるかに大きいx、idsの長さに合わせて)

私はfloor(id/5)でグルーピングを試みましたが、文字列の長さの問題が修正されましたが、idsが連続していないか、わずかなIDで多くの結果が得られますが、理想的ではありません。

+0

'ROLLBACK'コマンドで何が問題になっていますか?なぜあなたはここで何かする必要がありますか? – mathguy

+1

@mathguy - OPは "バックアウト"スクリプトを意味すると思う。 – GurV

+0

@GurV:そうだね。私がそれをロールバックと呼ぶ理由は、データベースだけでなく大規模な変更をロールバックするプロシージャの一部になるためです。 – Superole

答えて

3

あなたはバケットに各IDを割り当てるために、サブクエリ(インライン・ビューまたはCTE)を使用して、あなたのグループごとに句ことを含めることができます

select '... set code='||code||' where id in (' 
|| listagg(id,',') within group (order by id) 
|| ');' as RB_STMT 
from (
    select id, code, ceil(row_number() over (partition by code order by id)/5) as bucket 
    from mytable 
) 
where code in (121212,151515) 
group by code, bucket; 

RB_STMT                   
-------------------------------------------------------------------------------- 
... set code=121212 where id in (1234,1235,1236,1237,1238); 
... set code=121212 where id in (1239,2111,2112,2123,2124); 
... set code=121212 where id in (2125,2126,2136); 
... set code=151515 where id in (1456,2345,2468,2469,2470); 

、独自のサブクエリは次のように出力を生成します:

 ID  CODE  BUCKET 
---------- ---------- ---------- 
     1234  121212   1 
     1235  121212   1 
     1236  121212   1 
     1237  121212   1 
     1238  121212   1 
     1239  121212   2 
     1456  151515   1 
     2111  121212   2 
     2112  121212   2 
     2123  121212   2 
     2124  121212   2 
     2125  121212   3 
     2126  121212   3 
     2136  121212   3 
     2345  151515   1 
     2468  151515   1 
     2469  151515   1 
     2470  151515   1 

コード121212の最初の5つのIDはすべてバケット1です。次の5つはすべてバケツ2を持っています。最後の4つはバケット3です。151515のバケットは1から再び開始されます。コードとバケットの両方でグループ化すると、最終的な文字列に集約する短いリストが得られます。

さらに多くの行を表示するには、5をもっと高い値に変更してください。


あなたは問題があなたの更新をコミットした後まであります知ることができませんと仮定すると、そのロールバックはオプションではありません - あなたはバックアウト戦略ではなく、「ロールバック」スクリプトを作成している - 他にオプションには次のものがあります:テーブルをエクスポートし、元に戻す必要がある場合は切り捨て/インポートします。またはテーブルのバックアップコピーを作成してコピーに戻すか、更新を行うために使用します。または多分私が考えていないいくつかの他の人。

+0

'partition by'はまさに私が欲しかったものです:D今私は私の髪を引っ張るのを止めることができます。 – Superole