3

如何在 Java 中进行这样的查询并获得结果:

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

或者,我认为如果我从此查询在 Postgres 中创建过程会更好。

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'

并称之为

Connection ce_proc= null;
ce_proc = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgis","postgres","123456");
java.sql.CallableStatement proc =  ce_proc.prepareCall("{get_geom_difference()}");
proc.execute();
proc.close();
ce_proc.close();

但是如何在 Java 中从这个过程中得到结果呢?

更新

我试过这个SP

DROP FUNCTION get_geom_difference();

CREATE OR REPLACE FUNCTION get_geom_difference()
RETURNS integer AS
$$
DECLARE

tt integer;
BEGIN
SELECT filedata.num INTO tt
FROM filedata
Where filedata.num=1;
RETURN tt;

END;
$$
LANGUAGE 'plpgsql'

并打电话

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.executeQuery(); 
ResultSet results = (ResultSet) proc.getObject(1);

并得到一个错误:

in lineorg.apache.jasper.JasperException:在第 25 行proc.executeQuery()处处理 JSP 页面 /commit_changes.jsp 时发生异常;

根本原因 javax.servlet.ServletException:org.postgresql.util.PSQLException:查询未返回任何结果

但查询

SELECT filedata.num 
FROM filedata
Where filedata.num=1;

返回1

错在哪里?

4

5 回答 5

2

有很多不同的CallableStatement构造函数,但只有其中两个可以让您返回结果

AResultSet由 . 返回CallableStatement.executeQuery()。上面的链接中有一个很好的完整示例。

我不知道从 a 返回标量结果CallableStatement是否合法。不过,我希望PgJDBC将它转换为一行的行集,所以它应该可以工作。

于 2012-08-08T12:16:31.107 回答
2

您可以在很大程度上简化该功能。(为了这个问题,保持简单的功能。)

CREATE OR REPLACE FUNCTION get_geom_difference()
   RETURNS integer AS
$BODY$
   SELECT num
   FROM   filedata
   WHERE  num = 1 
   LIMIT  1;  -- needed if there can be more than one rows with num = 1
$BODY$    LANGUAGE SQL;

尽管从技术上讲,您在问题中的内容也可以使用 - 只要数据类型匹配。可以?filedata.num是类型的列integer吗?这就是我从示例中收集到的信息。关于你的另一个问题,我假设numeric缺乏信息。其中至少有一个会失败。

如果函数的返回类型与返回值不匹配,您会从 PostgreSQL 函数中得到一个错误。如果配置正确,在这种情况下,您的 PostgreSQL 日志将包含详细的错误消息。

当您在 PostgreSQL 中创建上述函数然后调用时,您会看到什么:

SELECT get_geom_difference(1);

psql。(最好在同一个会话中排除数据库、端口、服务器或用户的混合。)

调用一个带一个参数并返回一个标量值的简单函数似乎很简单。PostgreSQL JDBC 手册的第 6.1 章有一个完整的示例,它似乎与您的问题完全一致(不过,我的专长是 Postgres 而不是 JDBC)。

于 2012-08-09T07:29:39.927 回答
0

您的查询示例很典型。所以你需要的是

Java 数据库连接 (JDBC)

以及为它提供服务所需的一切都在包java.sql中

因此,在这一点上,我建议您阅读一些教程,如果您有一些特殊问题,请在 SO 上写下它。

于 2012-08-08T07:33:25.467 回答
0

您将需要 JDBC 来执行此操作。您应该能够在此处找到所有 JDBC 相关信息。

在此处查看有关如何将 Java 应用程序连接到 PostgreSQL 的更详细的教程。

于 2012-08-08T07:35:50.053 回答
0

适用于 100% java 7 和 postgres pgadmin 2016,在您的事务中使用 createNativeQuery 编写并更改myschema.mymethodThatReturnASelect

用于方案和函数的名称。

@Override
    public List<ViewFormulario> listarFormulario(Long idUsuario) {
        List<ViewFormulario> list =null;
        try {
            Query q = em.createNativeQuery("SELECT * FROM myschema.mymethodThatReturnASelect(?);");
            q.setParameter(1, idUsuario);

             List<Object[]> listObject = (List<Object[]>) q.getResultList();
            if (listObject != null && !listObject.isEmpty()) {
                list = new ArrayList<>();
                for (Object o[] : listObject) {
                    ViewFormulario c = new ViewFormulario();
                    c.setIdProyecto(o[0] != null ? Long.valueOf(o[0].toString()) : -1L);

……等等……等等。

于 2016-02-17T23:14:28.187 回答