无法使用Postgres存储函数获取ID - 类型int的值不正确

时间:2017-02-06 13:43:39

标签: java postgresql jdbc stored-functions

我正在尝试从架构位置获取位置信息。 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));

1 个答案:

答案 0 :(得分:3)

您正在从表中返回一行,该表是专门为每个关系创建的数据类型。因此,不是获得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;