2

我正在使用 Groovy 的 Sql 对象对 postgres 数据库执行查询。查询执行如下:

List<Map> results = sql.rows("select * from my_table")
List<Map> result2= sql.rows("select * from my_second_table")

我有一个 groovy 方法,它执行两个查询,然后进行一些处理以遍历数据以制作不同的数据集,但是,在某些情况下,我收到 postgres 异常"This ResultSet is closed"错误。

经过搜索,我最初认为这可能与这里的问题有关:SQLException: This ResultSet is closed (running multiple queries and trying to access the data from the resultsets after the fact) - 但是,我们似乎只得到了异常相当高的负载 - 这表明它不像第一个数据集在执行第二个查询时关闭那样简单,就好像我希望它始终如一地发生的情况一样。

任何人都可以阐明 Groovy 的 Sql 对象如何处理这些情况或提出可能出现的问题吗?

4

2 回答 2

3

Groovy SQL 有点像一只奇怪的猫。易于用于简单的东西。如果你有更复杂的场景,你可能最好使用其他东西。恕我直言

我首先建议执行一个查询,将结果存储到一个集合中,执行第二个查询并将结果存储在一个集合中,然后在两个集合而不是结果集之间进行操作。如果您的数据太大,请在开始进行聚合或其他操作之前找到某种方法在本地存储数据。

如果您不喜欢这样,您可能需要查看 GDK 源代码以更好地了解与结果集等相关的 Sql.getInstance() 做了什么。然后您可以回避您无意中踩到的任何地雷.

于 2012-09-20T03:18:05.440 回答
0

也许

List<Map> results = sql.rows("select * from my_table")
List<Map> result2= sql.rows("select * from my_second_table")

即使在纯 Java 中也不起作用(正如您在第二次调用时提供的答案中已经说过的那样,必须释放前一次调用期间专用的所有资源)。正如@Todd W Crone 提到的, Groovy 可以优化资源,例如动态释放它们或根据特定运行不释放它们。

实际上我只尝试了一个查询。例如,我尝试获取ResultSet然后遍历它,就像这样(不要介意表和字段的名称,查询相当简单;结果是由于LIMIT 1子句而包含一列的一行):

def resultSet = sql.executeQuery("SELECT age FROM person WHERE id = 12345 LIMIT 1")
resultSet.next()

并得到此 ResultSet 已关闭错误。似乎 Groovy 优化了资源并ResultSet立即关闭。我没有查看 Groovy SDK 的源代码。我发现eachRow和其他带有闭包式处理程序的方法工作正常,并且不会抛出This ResultSet is closed错误。

也许,带有闭包式处理程序的方法可以帮助您。例如,查看文章中的 except ,其中 rows() 方法使用了闭包

String query = 'select id as identifier, name as langName from languages'
def rows = db.rows(query, { meta ->
    assert meta.tableName == 'languages'
    assert meta.columnCount == 2
    // ...
})
于 2016-12-07T14:10:58.577 回答