如何用Java调用PostgreSQL程序?

时间:2012-08-08 07:30:23

标签: java postgresql

如何在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);

并收到错误:

  

org.apache.jasper.JasperException:处理发生异常   第25行in line proc.executeQuery();

的JSP页面/commit_changes.jsp      

根本原因javax.servlet.ServletException:   org.postgresql.util.PSQLException:没有返回结果   查询

但查询

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

返回1

哪里出错?

5 个答案:

答案 0 :(得分:2)

有很多不同的CallableStatement构造函数,但是only two of them let you get results back

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

我不知道从CallableStatement获取标量结果是否合法。我希望PgJDBC将其转换为一行的行集,因此应该工作。

答案 1 :(得分: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是?这就是我从这个例子中收集的内容。在your other question,由于缺乏信息,我假设numeric。至少其中一个会失败。

如果函数的返回类型与返回的值不匹配,则会从PostgreSQL函数中获得错误。正确配置后,PostgreSQL日志在这种情况下会有详细的错误消息。

当你在PostgreSQL中创建上述函数然后调用:

时,你看到了什么
SELECT get_geom_difference(1);
来自psql

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

调用一个简单的函数获取一个参数并返回一个标量值似乎非常简单。 Chapter 6.1 of the PostgreSQL JDBC manual有一个完整的例子,似乎与你在问题中的内容完全一致(尽管我的专长是与Postgres而不是JDBC)。

答案 2 :(得分:0)

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

Java Database Connectivity (JDBC)

以及维护它所需的一切,都在包java.sql

所以在这一点上,我重新想起你阅读一些教程,如果你有一些特殊的问题在SO上写下来。

答案 3 :(得分:0)

你需要JDBC才能做到这一点。您应该能够找到所有与JDBC相关的信息here

查看here以获取有关如何将Java应用程序连接到PostgreSQL的更详细教程。

答案 4 :(得分: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);

...等...等