从PL/pgSQL函数返回行

Kli*_*Max 1 java postgresql jdbc plpgsql

我在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'
Run Code Online (Sandbox Code Playgroud)

我在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);
Run Code Online (Sandbox Code Playgroud)

但是当我尝试在JDBC中调用该过程时,我得到了

错误org.apache.jasper.JasperException:在第25行处理JSP页面/commit_changes.jsp时发生异常

第25行是: proc.execute();

Erw*_*ter 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;
Run Code Online (Sandbox Code Playgroud)

您正在返回一个复合类型的SET(两列),您必须相应地声明该函数.RETURNS TABLE这是最方便的方法.

请确保对查询中的列名进行表限定,以使它们不与OUT同名的列冲突.

您可以使用language SQL函数进行此基本查询(或者您可以只执行原始SQL),不需要plpgsql.

在SQL中调用该函数

SELECT * FROM get_geom_difference();
Run Code Online (Sandbox Code Playgroud)

通过JDBC完成

我在这里引用手册

不应通过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();
Run Code Online (Sandbox Code Playgroud)

你也可以使用refcursor.阅读手册中的更多内容.