2016-08-24 12 views
0

を返し、私はここで私は数字の繰り返し次のループではので、10000で数字をインクリメントし続けるJavaプログラムオラクル/ ExadataのROWNUM範囲が重複行

select a, b, c, d from (
     select rownum r, a, b, c, d from foo order by c asc 
) where r >= 40001 and r < 50001 

のループのためにExadataの上でこのクエリを実行しています50001と60001になります。

私は行をとり、別のデータベースに挿入して再度ループします。私は私のソース(のExadata)データベースをチェックすると

現在、自分のコードが

Exception in thread "main" java.sql.BatchUpdateException: Duplicate entry '[email protected]' for key 'PRIMARY' 
    at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1809) 
    at 

ようなランダムエラーが発生し、1つだけの行が= 23およびb = [email protected]です。ソースには重複がありません。

ターゲットデータベースをチェックすると、行a = 23、b = [email protected]が前回のループ反復ですでに挿入されていることがわかります。 {{プログラムの開始時に宛先テーブルを削除して再作成します}}

私のウィンドウのクエリが同じ行を繰り返し返すようです。

私は、検索の多くを行なったし、私は私のウィンドウクエリが重複を返すべきではないことをかなり確信している...しかし、それは

を行うようにそう私に教えて...私はオラクル/ Exadataの専門家ではないよと思われます異なるrownum範囲で実行した場合、上記のクエリが同じ行を返すことができる変更がある場合。

+2

またはソート列の更新。 –

答えて

1

実際にはウィンドウ関数であるrow_number() over()を使用してください。 abはレコードをユニークにするように思われるので、試してみるべきです。

select a, b, c, d 
    from (
     select row_number() over (order by a,b) as r, 
       a, b, c, d 
      from foo 
     ) 
    where r >= 40001 
     and r < 50001; 

PS:このメソッドでは、読み込み中にDMLのオーバーソーステーブルを使用しないでください。 PS2:rownumは、注文の前に割り当てられているため、この場合は決して動作しません。 More info

+0

はい、row_number()はウィンドウ関数です。それはない – vercelli

+0

DMLにも挿入と削除が含まれています。 order byの最初の位置にある新しい行がある場合は、重複することになります。既に転送された行の削除がある場合は、別の行が欠落する可能性があります。 – vercelli

関連する問題