我在PostgreSQL中有一个程序:
CREATE OR REPLACE FUNCTION get_geom_difference()
RETURNS void AS
$$
BEGIN
SELECT filedata.num,st_area(ST_Difference(ST_TRANSFORM(filedata.the_geom,70066),filedata_temp.the_geom))
FROM filedata, filedata_temp
Where filedata.num=filedata_temp.num
end;
$$
LANGUAGE 'plpgsql'
我用Java调用它并希望获得此过程的结果。如何更改此过程以使其成为可能?以及如何在JDBC中使用它?
现在我用它:
Integer fileId;
Class.forName("org.postgresql.Driver");
Connection connect= null;
connect = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgis","postgres","123456");
java.sql.CallableStatement proc = connect.prepareCall("{?=call get_geom_difference()}");
proc.registerOutParameter(1, java.sql.Types.Integer);
proc.execute();
ResultSet results = (ResultSet) proc.getObject(1);
while (results.next()) {
fileId=r.getInt("num");
}
proc.close();
connect.close();
out.println(fileId);
但是当我尝试在JDBC中调用该过程时,我得到了
错误org.apache.jasper.JasperException:发生异常 在第25行处理JSP页面/commit_changes.jsp
第25行是:proc.execute();
答案 0 :(得分:7)
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;
您正在返回一个复合类型的SET(两列),您必须相应地声明该函数。 RETURNS TABLE
是最方便的方法。
请务必对查询中的列名进行表限定,以使它们不会与同名的OUT
列冲突。
您可以使用language SQL
function进行此基本查询(或者您可以只执行原始SQL),不需要plpgsql。
SELECT * FROM get_geom_difference();
我引用手册here
不应通过调用将数据作为集合返回的函数 CallableStatement接口,但应该使用正常 Statement或PreparedStatement接口。
我也从网站上采用了这个例子并对其进行了调整:
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();
您也可以使用refcursor。阅读more in the manual。
答案 1 :(得分:1)
在您的定义中,您的函数不返回RETURNS void
。
如果您想要num数据类型,只需更改为RETURNS numeric
。另外,要使其工作,请执行select到某个数值变量SELECT INTO var
并将return var
添加到函数末尾。
答案 2 :(得分:1)
虽然Erwin提供了一个很好的答案,但我认为我分享了一个函数采用params的版本,并且我在函数体内使用了新的postgres返回查询语法。不同之处在于它似乎设置了params,你必须使用PreparedStatement接口而不是更高级别的Statement。 这是我的pg功能
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;
这里的java只是用数据填充地图
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;
}
希望这有助于某人。