gpt4 book ai didi

database - 在 Scala 中功能性地处理数据库游标

转载 作者:搜寻专家 更新时间:2023-10-30 19:53:42 26 4
gpt4 key购买 nike

当我需要使用 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 中这样做,我可能会想出一个涉及 monad 的解决方案,但我不想把我的想法放在那些“曲折的小段落,都是一样的”上,因为它可能永远不会回来......

最佳答案

这是我想出的一个 Scala 解决方案:

@tailrec
def processCursor(query: => ResultSet)(process: ResultSet => Unit) {
@tailrec
def loop(resultSet: ResultSet,
processed: Boolean): Boolean = {
if (!resultSet.next()) processed
else {
process
loop(resultSet, true)
}
}
if (loop(query, false)) processCursor(query)(process)
}

这样调用它:

begin transaction
execute("declare cursor...")

processCursor(statement.executeQuery("fetch forward...")) {
resultSet =>
// process current row of the ResultSet
}

close cursor
commit

如何改进?

关于database - 在 Scala 中功能性地处理数据库游标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12786054/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com