I have a procedure in PostgreSQL:
CREATE OR REPLACE FUNCTION get_geom_difference()
RETURNS void AS
$$
BEGIN
SELECT filedata.num,st_area(ST_Difference(ST_TRAN
CREATE OR REPLACE FUNCTION get_geom_difference()
RETURNS TABLE (num mumeric, my_area geometry) AS
$BODY$
SELECT f.num
,st_area(ST_Difference(ST_TRANSFORM(f.the_geom, 70066), t.the_geom))
FROM filedata f
JOIN filedata_temp t USING (num);
$BODY$
LANGUAGE sql;
You are returning a SET of a composite type (two columns), you have to declare the the function accordingly. RETURNS TABLE is the most convenient way to do this.
Be sure to table-qualify the column names in the query so they do not conflict with OUT
columns of the same name.
You can use a language SQL function for this basic query (or you could just execute the raw SQL), no need for plpgsql.
SELECT * FROM get_geom_difference();
I quote the manual here
Functions that return data as a set should not be called via the CallableStatement interface, but instead should use the normal Statement or PreparedStatement interfaces.
I also took this example from the site and adapted it:
Statement stmt = conn.createStatement();
stmt.execute(" <function definition from above goes here> ");
ResultSet rs = stmt.executeQuery("SELECT * FROM get_geom_difference();");
while (rs.next()) {
// do something
}
rs.close();
stmt.close();
You could also use a refcursor. Read more in the manual.
Although Erwin provided a great answer, I thought I'd share a version in which the function takes params, and I'm using the new postgres return query syntax within the body of the function. The difference is that it seems to set params you have to use the PreparedStatement interface rather than the higher level Statement. here's my pg function
CREATE OR REPLACE FUNCTION gettools(_userid bigint)
RETURNS table(id bigint,itemname character varying(250)) AS
$BODY$
begin
return query
select distinct a.id, a.itemname
from tool a inner join tooltie b
on a.id = b.toolid
and b.userid=_userid;
end;
$BODY$
LANGUAGE plpgsql STABLE
COST 100;
and here's my java that simply fills a map with data
private static final String GET_DATASOURCES = "select * from getdatasources(?)";
public Map<Long, String> getAuthDataSources(Long userid) {
Map<Long, String> auths = new TreeMap<>();
try {
if (connection == null || connection.isClosed()) {
init();
}
PreparedStatement cs = connection.prepareStatement(GET_DATASOURCES);
// this is where to set the param ? for the function
cs.setLong(1, userid);
connection.setAutoCommit(false);
ResultSet result = cs.executeQuery();
while (result.next()) {
Long id = result.getLong(1);
String itemname = result.getString(2);
auths.put(id, itemname);
}
cs.close();
connection.commit();
connection.setAutoCommit(true);
connection.close();
} catch (SQLException ex) {
LOG.error("error getting data sources", ex);
}
return auths;
}
Hope this helps someone.
In your definition your function returns nothing RETURNS void
.
If you want num data type just change to RETURNS numeric
. Also, To make it worked, perform select into some numeric variable SELECT INTO var
and add return var
to the end of function.