2017-02-16 75 views
0

我正在遷移一些數據,但在執行操作之前我想要生成回滾腳本。Oracle listagg組x行數

下表中的重要列可能是這樣的:

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

我改變所有代碼121212151515252525,但我需要能夠改變他們回來,如果出現問題的其他地方。

因此,我開始使用listagg創建逗號分隔的id列表,我可以在更新語句的where-clause中使用它。沿着這些路線的東西:

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; 

這完全適用於小套,就像在我的開發環境,但在生產中我打的字符串長度(ORA-01489)的限制。

所以我想什麼,能夠做的就是按ID的x個除了代碼,從而爲X = 5會是這個結果:

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. 

(我會使用一個更大的x在現實當然;適應於ID的長度)

我試着編組floor(id/5),並修復了字符串長度問題,但因爲ID不是順序的,或均勻間隔,我最終與很多結果只有幾個ID,這也不是很理想。

+0

「ROLLBACK」命令有什麼問題?你爲什麼需要在這裏做任何事情? – mathguy

+1

@mathguy - 我認爲OP意味着一個「退出」腳本 – GurV

+0

@GurV:是的,我想。我稱之爲回滾的原因是因爲它將成爲程序的一部分,回滾一個大的變化,不僅涉及數據庫。 – Superole

回答

3

你可以使用子查詢(內嵌視圖或CTE)每個ID分配給一斗,幷包括在你的小組by語句:

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的前五個ID全部具有桶1;接下來的五個都有桶2;最後四個有桶3.151515的桶再次從1開始。通過代碼和桶進行分組,給你一個簡短的列表來聚合成最終的字符串。

要更多每行,請將5更改爲更高。


假設你不會知道有一個問題,直到您已經提交您的更新後,所以回滾是不是一種選擇 - 所以你要創建一個退出戰略,而不是一個「回退」腳本 - 其他選項包括:如果需要還原表,則導出表並截斷/導入;或者創建表的備份副本並恢復到副本或使用它來執行更新;或者可能還有其他一些我沒有想到的。

+0

'partition by'正是我想要的:D現在我可以停止拉我的頭髮。 – Superole