2

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

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

如何从 java 调用此函数并正确传递 args?

4

4 回答 4

3

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

例如:

// 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();

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

于 2013-07-02T20:27:32.623 回答
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 函数的代码。

有关更多详细信息,请参见 使用 java 的 Postgresql 函数

于 2017-11-11T13:56:11.647 回答
1

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

CallableStatement statement = connection.prepareCall(" { call function( ?, ?, ? ) } ");

statement.setInt(1, value);
statement.setInt(2, value);
statement.setInt(3, value);
statement.execute();
statement.close();

请注意,在实际的 sql 代码中没有? =前面,并且没有对方法的调用。callregisterOutParameter

于 2015-04-09T08:10:27.980 回答
0

使用 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;
  }
于 2016-02-17T23:12:18.003 回答