1

我在 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();

4

3 回答 3

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函数(或者您可以只执行原始 SQL),不需要 plpgsql。

在 SQL 中调用函数

SELECT * FROM get_geom_difference();

通过 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();

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

于 2012-08-08T14:48:37.653 回答
1

在您的定义中,您的函数没有返回任何内容RETURNS void。如果您想要 num 数据类型,只需更改为RETURNS numeric. 此外,要使其正常工作,请对某个数字变量执行选择SELECT INTO var并添加return var到函数的末尾。

于 2012-08-08T10:58:39.563 回答
1

尽管 Erwin 提供了一个很好的答案,但我想我会分享一个函数接受参数的版本,并且我在函数体内使用了新的 postgres 返回查询语法。不同之处在于它似乎设置参数你必须使用 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;
      }

希望这可以帮助某人。

于 2015-01-08T17:13:14.457 回答