2016-11-23 45 views
0

私は何百万と何百万もの行を持つ巨大なテーブルを持っています。ランダムなsys_guid()を使用して重複行とヌル行を更新し、主キーを追加します

GUID RAW(16バイト)の列があります。何らかの理由でこのテーブルにプライマリキー制約がありませんでした。コードのバグにより、重複がGUID列に挿入されていました(一部のヌル値も)

私がしたいのは

です
  • 更新GUIDは(SYS_GUIDを使用して()可能性が高い)ランダムに生成GUIDを持つNULLであるすべての行
  • 更新GUIDが
  • ランダム生成されたGUIDがテーブルに主キーを追加して重複しているすべての行、GUID列を使用します。

GUID値は保持する必要はなく、すべてが一意である必要があります。しかし、問題のテーブルには約3億レコードがありますので、私はそれを行う方法を探しています。それはあまりにも多くのダウンタイムを招かないでしょう。

おかげ

+0

複製物とは何ですか?私たちはどのレコードが「オリジナル」なのかを知っていて、それを置き換えないようにする必要があります。テーブル構造を含めてください。 –

+0

重複する行はなく、GUID値のみが複製されます。したがって、全く異なるレコードの中には同じGUIDがあります。 – bbedward

+0

3つのGUIDが同じです。どれを変更するのか、どの3つを変更するべきか、どのようにしてわかりますか?あなたはテーブル構造を投稿できますか? –

答えて

1

私は、MERGE文を使用したい、の線に沿って何か:

merge into your_table tgt 
    using (select guid, 
       row_id 
     from (select guid, 
         rowid row_id, 
         row_number() over (partition by guid order by rowid) rn 
       from your_table) 
     where rn != 1) src 
    on (tgt.rowid = src.rowid) 
when matched then 
update set guid = null; 

更新を行い、その後、一意のインデックスを追加します。

update your_table 
set guid = sys_guid() 
where guid is null; 

その後、あなたを変えますguidカラムをnullにできないようにし、最後に主キー制約を追加します。

また、マージでヌルと重複するGUID行をsys_guid()に更新することもできますが、重複するguidが作成される危険性があります。 sys_guid()は必ずしも一意の値を生成するとは限りませんので、最後の更新は失敗する可能性があります。

個人的には、私はguidをスクラップしていましたが(これは必ずしも可能ではないとわかっていますが)、シーケンスと一緒に行きます。一意性を保証するのはずっと簡単です!

+0

ありがとう、これはトリックを行うように見えました。残念ながら私の状況ではguidを破棄することはできません。 – bbedward

関連する問題