0

Javaプログラムのforループでexadataに対してこのクエリを実行しています

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

ここでは、数値を 10000 ずつインクリメントし続けるため、次のループ反復では、数値は 50001 と 60001 になります。

行を取得して別のデータベースに挿入し、再びループします。

現在、私のコードは次のようなランダムなエラーに遭遇します

Exception in thread "main" java.sql.BatchUpdateException: Duplicate entry '23-ABC@XYZ.COM' for key 'PRIMARY'
    at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1809)
    at 

ソース (exadata) データベースを確認すると、a=23 および b = ABC@XYZ.COM の行が 1 つしかありません。したがって、ソースには重複がありません。

ターゲット データベースを確認すると、行 a=23, b = ABC@XYZ.COM が前のループ反復で既に挿入されていることがわかります。{{プログラムの開始時に宛先テーブルをドロップして再作成します。}}

そのため、ウィンドウ クエリが同じ行を何度も返しているようです。

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

私は oracle/exadata の専門家ではありません。異なる rownum 範囲で実行した場合に上記のクエリが同じ行を返す可能性があるという変更があるかどうか教えてください。

4

1 に答える 1

1

これrow_number() over()は実際にはウィンドウ関数です。aとがレコードをユニークにしているように見えるので、b試してみてください。

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は注文前に割り当てられるため、この場合は機能しません。詳細情報.

于 2016-08-24T16:30:36.110 に答える