无法使用 Postgres 存储函数获取 ID - int 类型的值错误

Posted

技术标签:

【中文标题】无法使用 Postgres 存储函数获取 ID - int 类型的值错误【英文标题】:Unable to fetch ID using Postgres Stored Function - Bad value for type int 【发布时间】:2017-02-06 13:43:39 【问题描述】:

我正在尝试从架构位置获取位置信息。 Postgres 版本是9.3.15,使用的maven jar 是9.4-1200-jdbc4 ubuntu 14.04 LTS。对于连接池,我使用的是mchange 版本0.9.5.2

org.postgresql.util.PSQLException: Bad value for type int : -,24.7477464699999992,32.7477464700000027,232328,xxxx,xxxxx,xxxx,"xxxx",India,landmark
    at org.postgresql.jdbc2.AbstractJdbc2ResultSet.toInt(AbstractJdbc2ResultSet.java:2962)
    at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getInt(AbstractJdbc2ResultSet.java:2145)
    at com.mchange.v2.c3p0.impl.NewProxyResultSet.getInt(NewProxyResultSet.java:425)
    at com.creo.hike.direct.storage.jdbc.service.LocationService.getLocation(LocationService.java:74)
    at com.creo.hike.direct.storage.jdbc.service.LocationService.getLocation(LocationService.java:66)
    at com.creo.hike.direct.testapp.App.testLocationService(App.java:38)
    at com.creo.hike.direct.testapp.App.main(App.java:19)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

位置架构。

CREATE TABLE Location (
    LocationId  SERIAL PRIMARY KEY,
    Latitude    DOUBLE PRECISION NOT NULL DEFAULT 0.0,
    Longitude   DOUBLE PRECISION NOT NULL DEFAULT 0.0,
    Pincode     INTEGER NOT NULL DEFAULT 0,
    InnerAddress TEXT NOT NULL DEFAULT 'Unknown',
    Locality     TEXT NOT NULL DEFAULT 'Unknown',
    City         TEXT NOT NULL DEFAULT 'Unknown',
    State        TEXT NOT NULL DEFAULT 'Unknown',
    Country      TEXT NOT NULL DEFAULT 'Unknown',
    Landmark     TEXT NOT NULL DEFAULT 'Unknown'
);

位置插入运行良好,但是当尝试使用生成的LocationId 获取位置时,使用存储函数失败。 存储过程 - 通过 id gets_location_by_id 获取位置

CREATE OR REPLACE FUNCTION gets_location_by_id(
    localId INTEGER
 ) RETURNS Location AS $$
  DECLARE
     row Location%ROWTYPE;
  BEGIN
     SELECT * INTO row
     FROM Location
         WHERE LocationId = localId;
     RETURN row;
  END;
  $$ LANGUAGE plpgsql;

如果我在这里遗漏了什么,请告诉我。通过 id 获取位置的 Java 代码是

String sql = "SELECT gets_location_by_id(?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setInt(1, locationId);
ResultSet resultSet  = statement.executeQuery();
 location = new Location(
                resultSet.getInt(1),
                resultSet.getDouble(2),
                resultSet.getDouble(3),
                resultSet.getInt(4),
                resultSet.getString(5),
                resultSet.getString(6),
                resultSet.getString(7),
                resultSet.getString(8),
                resultSet.getString(9),
                resultSet.getString(10));

【问题讨论】:

您确定 SELECT * 将 LocationId, Latitude , Longitude, Pincode, ... 按此确切顺序返回到行中吗? 是的。它正在返回。 【参考方案1】:

您正在从表中返回一行,该行是专门为每个关系创建的数据类型。因此,您获得的不是 10 个值,而是 1 个复合值。您可以通过在查询中将该函数用作行源来轻松解决此问题:

String sql = "SELECT * FROM gets_location_by_id(?)";

您还可以按如下方式简化您的功能:

CREATE FUNCTION gets_location_by_id(localId INTEGER) RETURNS SETOF Location AS $$
BEGIN
    RETURN QUERY SELECT * FROM Location WHERE LocationId = localId;
END;
$$ LANGUAGE plpgsql;

【讨论】:

以上是关于无法使用 Postgres 存储函数获取 ID - int 类型的值错误的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spring Boot JPA 在 Postgres 中存储几何点?

Postgres存储函数如何返回表

Python/postgres/psycopg2:获取刚刚插入的行的 ID

如何在 jpa 查询中调用 postgres position() 函数

如何通过 postgres 中的存储函数压缩 CSV 文件

使用 Laravel Blade 从 Postgres 显示 JSON 数据