【问题标题】:call a stored function on postgres from java从java调用postgres上的存储函数
【发布时间】:2013-07-02 20:15:19
【问题描述】:

我在我的 Postgres 数据库中创建了以下函数:

CREATE FUNCTION funct(arg1 type1, arg2 type2, ...) RETURNS void AS $$
BEGIN
--insert passed args in some tables
END

如何从 java 调用这个函数并正确传递参数?

【问题讨论】:

  • 简单运行select funct(1, 2, 3)

标签: postgresql stored-procedures jdbc


【解决方案1】:

如果您了解如何使用 JDBC 与 postgres 对话(如果不是 this tutorial 应该可以让您快速上手),那么这个 JDBC page 将展示如何调用存储函数:

例如:

// Setup function to call.
Statement stmt = conn.createStatement();
stmt.execute("CREATE OR REPLACE FUNCTION refcursorfunc() RETURNS refcursor AS '"
        + " DECLARE "
        + "    mycurs refcursor; "
        + " BEGIN "
        + "    OPEN mycurs FOR SELECT 1 UNION SELECT 2; "
        + "    RETURN mycurs; "
        + " END;' language plpgsql");
stmt.close();

// We must be inside a transaction for cursors to work.
conn.setAutoCommit(false);

// Procedure call.
CallableStatement proc = conn.prepareCall("{ ? = call refcursorfunc() }");
proc.registerOutParameter(1, Types.OTHER);
proc.execute();
ResultSet results = (ResultSet) proc.getObject(1);
while (results.next()) {
    // do something with the results...
}
results.close();
proc.close();

在后面的链接中还讨论了其他类型的存储函数。

【讨论】:

  • 我已经阅读了该教程,但是:-我已经在我的数据库中声明了函数,我只需要从 java 客户端调用-我的函数不返回任何游标,只是 void
【解决方案2】:

调用 postgresql 函数/存储过程与普通的 Sql 调用有点不同。前段时间我也遇到过类似的问题,我搜索了很多,然后我找到了解决方案。下面我分享解决方案。

下面是postgresql函数

Create or Replace Function myfunction(id integer) Returns Table(empid integer,empname charactervarying) AS
$BODY$
DECLARE
var_r record;

BEGIN
FOR var_r IN(
select * from emp where empno=id
)

LOOP
empid:=var_r.empno;
empname:=var_r.empname;
RETURN NEXT;
end LOOP;

END; $BODY$
LANGUAGE plsql VOLATILE

当我们在 postgresql 控制台中运行查询时,它将根据表中 id=5 的记录给出结果

select myfunction(5);

现在我们必须编写代码来从 java 调用这个函数。下面是代码

public class Employee {
    public static void main(String[] args) {

    try {
    callProc();
    }Catch(SQLException e) {
    e.printStackTrace();
    }
    }

    public static void callProc () throws SQLException {



        Connection con=DBConnection.getConnection();
        Statement statement=con.createStatement();
    //Call to postgresql function   
        String query=" call myfunction(?)";
        CallableStatement ps=con.prepareCall(query);
        ps.setInt(1,5)  // it means we are setting value 5 at first index.
        ResultSet rs=ps.executeQuery();
        List<Emp> listOfEmp=new ArrayList<Emp>();

        while(rs.next()){

        Emp data=new Emp();
        data.setEmpno(rs.getInt("empid"));
        data.setEmpName(rs.getString("empid"));
        listOfEmp.add(data);

        }
        system.out.println("Total emp"+listOfEmp.size());
    }
}

在上面的示例中,我们编写了从 java 调用 postgresql 函数的代码。

更多详情请看这里 Postgresql Function with java

【讨论】:

    【解决方案3】:

    我知道这有点老了,但我偶然发现了同样的问题并自己找到了解决方案。这很简单,但我希望这可以供将来参考。

    CallableStatement statement = connection.prepareCall(" { call function( ?, ?, ? ) } ");
    
    statement.setInt(1, value);
    statement.setInt(2, value);
    statement.setInt(3, value);
    statement.execute();
    statement.close();
    

    请注意,在实际 sql 代码中,call 之前没有 ? =,并且没有调用 registerOutParameter 方法。

    【讨论】:

      【解决方案4】:

      使用 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);
                          c.setIdUsuario(o[1] != null ? Integer.valueOf(o[1].toString()) : -1);
                          c.setIsCreador(o[2] != null ? Boolean.valueOf(o[2].toString()) : null);
                          c.setIdPadre(o[3] != null ? Long.valueOf(o[3].toString()) : -1L);
                          c.setNombre(o[4] != null ? o[4].toString() : "");
                          c.setNombreCliente(o[5] != null ? o[5].toString() : "");
                          c.setCodigo(o[6] != null ? o[6].toString() : "");
                          c.setEstado(o[7] != null ? Long.valueOf(o[7].toString()) : -1L);
                          c.setTotalDisponible(o[8] != null ? Double.valueOf(o[8].toString()) : 0.0);
                          c.setCantidadAlmacenamiento(o[9] != null ? Double.valueOf(o[9].toString()) : 0.0);
                          c.setPorcentajeAlmacenamiento(o[10] != null ? Double.valueOf(o[10].toString()) : 0.0);
                          c.setCantidadUsuario(o[11] != null ? Long.valueOf(o[11].toString()) : 0);
                          c.setCantidadRegistros(o[12] != null ? Long.valueOf(o[12].toString()) : 0);
                          c.setMbFoto(o[13] != null ? Double.valueOf(o[13].toString()) : 0.0);
                          c.setMbVideo(o[14] != null ? Double.valueOf(o[14].toString()) : 0.0);
                          c.setMbTexto(o[15] != null ? Double.valueOf(o[15].toString()) : 0.0);
                          list.add(c);
                      }
                  }
              } catch (Exception e) {
                  System.out.println("listarFormulario " + e.getMessage());
              }
              return list;
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-01-09
        • 1970-01-01
        • 1970-01-01
        • 2012-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多