JDBCドライバーを使用してPostgreSQLデータベースから数百万のデータベース行を読み取る必要がある場合は、常にカーソルを使用します。そうしないと、OutOfMemoryErrorが発生します。これが私が使用するパターン(擬似コード)です:
begin transaction
execute("declare cursor...")
while (true) {
boolean processedSomeRows = false
resultSet = executeQuery("fetch forward...")
while (resultSet.next()) {
processedSomeRows = true
...
}
if (!processedSomeRows) break
}
close cursor
commit
これは、Scalaで実装するために私が思いついたより「機能的な」同等物です。
begin transaction
execute("declare cursor...")
@tailrec
def loop(resultSet: ResultSet,
processed: Boolean): Boolean = {
if (!resultSet.next()) processed
else {
// Process current result set row
loop(resultSet, true)
}
}
while (loop(executeQuery("fetch forward..."), false))
; //Empty loop
close cursor
commit
私はこれが考案されていることを知っていますが、可変性に頼らずにもっと良い方法はありますか?Haskellでこれをやろうとすると、モナドを使った解決策を思いつくかもしれませんが、二度と戻ってこないかもしれないので、それらの「ねじれた小さな通路」に頭を下げたくありません...