无法使用 Postgres 存储函数获取 ID - 类型 int 的值错误
Unable to fetch ID using Postgres Stored Function - Bad value for type int
我正在尝试从模式 Location 获取位置信息。
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'
);
Location 的插入工作正常,但是当尝试使用生成的 LocationId
获取 Location 时,使用存储函数失败。
存储过程 - 通过 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;
如果我在这里遗漏了什么,请告诉我。 Java 通过 id 获取位置的代码是
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));
您正在从 table 返回一行,该行的数据类型是专门为每个关系创建的。因此,您得到的不是 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;
我正在尝试从模式 Location 获取位置信息。
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'
);
Location 的插入工作正常,但是当尝试使用生成的 LocationId
获取 Location 时,使用存储函数失败。
存储过程 - 通过 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;
如果我在这里遗漏了什么,请告诉我。 Java 通过 id 获取位置的代码是
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));
您正在从 table 返回一行,该行的数据类型是专门为每个关系创建的。因此,您得到的不是 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;