3

あるデータベースから数百万行を読み取り、別のデータベースに書き込む必要があります。PreparedStatement.addBatch大きなバッチ(おそらく1000行)で書き込みを行うために使用したいと思います。それらがトランザクションに含まれている必要はありません。Scala 2.9.2 でコードを書いています。

これを行う 1 つの方法は次のとおりです。

val sourceResultSet = ...
val targetStatement = targetConnection.prepareStatement(...)
var rowCount = 0
while (sourceResultSet.next()) {
  // Read values from sourceResultSet and write them to targetStatement
  targetStatement.addBatch()
  rowCount += 1
  if (rowCount % 1000 == 0) {
    targetStatement.executeBatch()
    rowCount = 0
  }
}

を使用せずに、より機能的な方法でこれを行うにはどうすればよいvar rowCountですか? RAM の使用量も考慮する必要があります。数百万行を読み取っているため、一度にすべてのソース行をメモリに格納するソリューションは失敗します。

4

1 に答える 1

2

の種類はsourceResultSet何ですか? 使用状況に基づいてイテレータ/ストリームを想定していますが、いずれにしても、Scala コレクションを使用takeして一度に 1000 個の要素を取得できます (これはリスト、セット、イテレータ、ストリームなどで機能します)。より機能的に行うには (副作用のみであり、純粋な関数ではありません)、インライン関数を定義します。

def processSource(sourceResultSet: Iterator): Unit = {
  if(sourceResultSet.hasNext) {
    sourceResultSet.take(1000).foreach(row => /* Add to batch */)
    targetStatement.executeBatch()
    processResult(sourceResultSet) // How you handle the recursion depends on what sourceResultSet is
  }
}

val sourceResultSet = ...
val targetStatement = targetConnection.prepareStatement(...)
processSource(sourceResultSet)

sourceResultSet が遅延 (ストリームまたはイテレータ) である限り、一度にメモリにロードすることを回避できます。

于 2012-09-26T15:18:12.983 に答える