为啥我在从 Java 批量执行 PostgreSQL 存储过程时收到错误消息,提示“未预期结果”?

Posted

技术标签:

【中文标题】为啥我在从 Java 批量执行 PostgreSQL 存储过程时收到错误消息,提示“未预期结果”?【英文标题】:Why I'm getting an error informing that "a result was not expected" when executing stored procedures on PostgreSQL from Java in a batch?为什么我在从 Java 批量执行 PostgreSQL 存储过程时收到错误消息,提示“未预期结果”? 【发布时间】:2011-09-02 03:29:26 【问题描述】:

我在数据库中有这个程序:

CREATE OR REPLACE FUNCTION replacePageRelevance(id INT, value REAL) RETURNS VOID AS $$
BEGIN
INSERT INTO pageRelevance VALUES (id,value);
EXCEPTION WHEN unique_violation THEN
    UPDATE pageRelevance SET relevance = value WHERE pageId = id;       
END
$$
LANGUAGE plpgsql;

以及调用此函数的这段代码:

private final String PAGE_RELEVANCE_SQL = "SELECT replacePageRelevance(?,?::REAL)";
try (CallableStatement cstm = conn.prepareCall(PAGE_RELEVANCE_SQL)) 
        for (Map.Entry<Integer, Double> entry : weightMap.entrySet()) 
            cstm.setInt(1, entry.getKey());
            cstm.setDouble(2, entry.getValue());
            cstm.addBatch();
        
        cstm.executeBatch();
     catch (SQLException e) 
        LOGGER.error("Error discovering pages relevance: " + e.getNextException());
    

当我执行批处理时,值被插入或替换到表中,但在那之后,我收到一个异常通知 A result was returned when none was expected.

我不知道出了什么问题,是我调用程序的方式还是程序本身。可能是什么问题以及如何解决?

使用SELECT 调用过程是正确/唯一的方法吗?

【问题讨论】:

【参考方案1】:

据我所知,您在应该使用 call 时使用的是 SELECT

来自PostgreSQL documentation on the JDBC interface的一个例子:

// Turn transactions off.
con.setAutoCommit(false);
// Procedure call.
CallableStatement upperProc = con.prepareCall(" ? = call upper( ? ) ");
upperProc.registerOutParameter(1, Types.VARCHAR);
upperProc.setString(2, "lowercase to uppercase");
upperProc.execute();
String upperCased = upperProc.getString(1);
upperProc.close();

请注意,在您的情况下,结果的 ? = call 语法是不必要的 - 您只想使用 call replacePageRelevance(?,?::REAL)

此语法与实际 PostgreSQL 不同的原因是因为这是 JDBC specification 的一部分。

【讨论】:

@Renato - 你试过了吗? postgresql.org/docs/7.4/static/jdbc-callproc.html(找不到 9.0 的文档) 我只尝试用 CALL 代替 SELECT。我正在尝试使用此示例,但我的函数返回 VOID。 感谢您的帮助,与 call 合作。我只想强调call 必须小写。 @Renato - 啊,没有意识到,我的错误。回答已编辑并 +1,因为我也学到了一些东西。

以上是关于为啥我在从 Java 批量执行 PostgreSQL 存储过程时收到错误消息,提示“未预期结果”?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在从 C# 创建的进程中运行 bash 命令时我的 $PATH 不同?

为啥我在从 MS Access 数据库中提取的十进制值中添加了零?

为啥 Java 程序需要“main()”方法?

为啥有些字典键在从调试器打印时有引号而另一些没有?

为啥我在使用 SOAP 的贝宝批量付款上得到 transaction_status = "Failed"?

为啥我的数据没有在我的 SQLAlchemy 模型中正确表示?