来自 PostgreSQL 函数的多个 JDBC 结果集

Posted

技术标签:

【中文标题】来自 PostgreSQL 函数的多个 JDBC 结果集【英文标题】:Multiple JDBC ResultSets from PostgreSQL Function 【发布时间】:2014-07-15 15:51:44 【问题描述】:

我想编写一个 PLPGSQL(针对 PostgreSQL 9.3)函数,该函数将返回多个结果集(即,当通过 JDBC 访问时,我将调用 getMoreResults() 以移动到下一组行),但我所做的一切我试过要么给我一个语法错误,要么只是将所有内容连接到一个结果集中。

这是一个说明问题的简单示例:

CREATE TYPE my_type AS (a BIGINT, b TEXT, c DOUBLE PRECISION);

CREATE FUNCTION my_func(_arg1 TEXT, _arg2 TEXT)
  RETURNS SETOF my_type
AS $$
BEGIN
  RETURN QUERY SELECT a, b, c FROM table1 WHERE d = _arg1 AND e = _arg2;
  RETURN QUERY SELECT a, b, c FROM table2 WHERE d = _arg1 AND e = _arg2;
END;
$$ LANGUAGE PLPGSQL;

当我运行此命令时,table1 和 table2 中的行将连接在一起形成一个结果集。

我也尝试过类似的东西

CREATE FUNCTION my_func(_arg1 TEXT, _arg2 TEXT)
  RETURNS SETOF TABLE(a BIGINT, b TEXT, c DOUBLE PRECISION)

但这只会导致一个神秘的语法错误:ERROR: syntax error at end of input

为了完整起见,这里是我想用来处理结果的 Java 代码。我相当确定问题出在 db 函数方面,但我可能误解了 JDBC API 应该如何工作。

(为了便于阅读,删除了错误处理和资源关闭)

PreparedStatement statement = connection.prepareStatement("SELECT * FROM my_func(?, ?);");
statement.setString(1, "foo");
statement.setString(2, "bar");
statement.execute();
ResultSet rs1 = statement.getResultSet();
while(rs1.next()) 
    // Process first result set

statement.getMoreResults();
ResultSet rs2 = statement.getResultSet();
while(rs2.next()) 
    // Process second result set

根据我到目前为止所做的搜索,似乎这种类型的解决方案应该受 JDBC 和 PostgreSQL 支持,但我找不到任何明确的实际示例。

【问题讨论】:

【参考方案1】:

您可以从 PostgreSQL 获取多个结果集的唯一方法(在撰写本文时 - 当前为 PostgreSQL 9.4)是通过返回 refcursors。

为每个结果集定义您的函数RETURNS SETOF refcursor 然后return a cursor。 PgJDBC 会识别出它是一个引用并为你获取它;见the documentation。

【讨论】:

Postgres13 或即将推出的 Postgres14 的任何更新/改进?【参考方案2】:

稍微修改您的问题,但如果您不必使用函数,您可以像通常使用 JDBC 一样从 PostgreSQL 获取多个 ResultSet。只需使用getMoreResults() 连接您的查询并处理每个结果集。见Queries returning multiple result sets。

【讨论】:

以上是关于来自 PostgreSQL 函数的多个 JDBC 结果集的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL/JDBC - 如何准备调用带有参数 CITEXT (TEXT) 的函数?

“名称”类型的 PostgreSQL 函数参数存在问题

使用 JDBC 插入 PostgreSQL 时间类型时出错

无论是不是使用 UTF8 编码,Postgresql/JDBC 都会失败

如何在 Azure Databricks 中使用 JDBC 从 PostgreSQL 读取表数据?

java.jdbc clojure 执行!插入数量