【问题标题】:In Java, calling a PostgreSQL function, why I'm getting an error informing that the function doesn't exists?在 Java 中,调用 PostgreSQL 函数,为什么我收到一个错误,通知该函数不存在?
【发布时间】:2011-09-01 17:16:51
【问题描述】:

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

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;

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

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());
    }
}

这不起作用,我收到一条错误消息,通知 function replacepagerelevance(integer, double precision) doesn't exists.。为什么?

生成的调用是这样的:SELECT replacePageRelevance('882','8.0')。如果我在 pgAdmin 中执行它,它可以工作,但不是来自 Java。

【问题讨论】:

    标签: java postgresql stored-procedures plpgsql sqlexception


    【解决方案1】:

    这是因为您的 PL/pgSQL 函数定义为:

    replacePageRelevance(id INT, value REAL)
    

    REAL 是单精度浮点数,但在 Java 端,您尝试将其用作双精度,并且没有针对这种情况的隐式转换。

    您应该使用 CallableStatement.setFloat 单精度 REAL 数据类型,但它并不清楚,因为阅读 Java API:

    将指定参数设置为给定的 Java 浮点值。这 驱动程序在将其发送到 数据库。

    由于 FLOAT 在 Postgres 中是 DOUBLE PRECISION同义词,它的运行效果与 CallableStatement.setDouble 产生错误消息的效果相同(这很奇怪)。

    当然,您可以将您的函数更改为 replacePageRelevance(id INT, value DOUBLE PRECISION),并且我检查过它适用于您的代码。

    尽管如此,如果你想在你的函数中保留REAL),那么使用这样的显式转换:

    String PAGE_RELEVANCE_SQL = "{call replacePageRelevance(?, ?::real)}";
    

    【讨论】:

    • 什么PostgreSQL类型兼容双精度?
    • @Renato:就double precision
    • 感谢您的回答和解释。我现在正在使用转换,因为我不需要太多的精度
    猜你喜欢
    • 2017-03-09
    • 2019-05-09
    • 1970-01-01
    • 2022-08-24
    • 1970-01-01
    • 2019-08-19
    • 1970-01-01
    • 1970-01-01
    • 2020-10-22
    相关资源
    最近更新 更多