如何在Java中访问从PostgreSQL返回setof refcursor的过程?

需要访问从PostgreSQL返回setof refcursor的过程。

我能够访问第一个对象,但不能访问对象的其余部分而不是其余的对象。

con.setAutoCommit(false); try (CallableStatement proc = con.prepareCall("{ ? = call usp_sel_article_initialdata_new1() }")) { proc.registerOutParameter(1, Types.OTHER); proc.execute(); ResultSet results = (ResultSet) proc.getObject(1); while (results.next()) { System.out.println("Result Id" + results.getString(1)); System.out.println("Results Name" + results.getString(2)); } 

这给了我第一个refcursor值但是当我尝试使用第二个refcursor它给我错误我使用这一行:

 proc.registerOutParameter(2, Types.OTHER); 

这是错误的。 还尝试过:

 proc.registerOutParameter(1, Types.REF); 

这也行不通。 程序示例是:

  CREATE OR REPLACE FUNCTION usp_sel_article_initialdata_new1() RETURNS SETOF refcursor AS $BODY$ Declare swv_refcur refcursor; swv_refcur2 refcursor; DECLARE r record; BEGIN open SWV_RefCur for Select OM.opID as ID,OM.OperatorName as Name from operator AS OM (OPid bigint,OperatorName character varying(100),status boolean) where OM.status = true order By OperatorName; return next SWV_RefCur; open SWV_RefCur2 for Select CC.cirid as ID,CC.cirnm as Name from circle AS CC (cirid bigint,cirnm character varying(100),status boolean) where Status = true and cirid not in(28,31) order by cirnm; return next SWV_RefCur2; 

请帮我如何访问第二个对象。

returns setof refcursor意味着你得到一个常规ResultSet ,其中每个“row”在调用getObject()时包含另一个 ResultSet:

以下为我工作:

 ResultSet rs = stmt.executeQuery("select * from usp_sel_article_initialdata_new1()"); if (rs.next()) { // first result set returned Object o = rs.getObject(1); if (o instanceof ResultSet) { ResultSet rs1 = (ResultSet)o; while (rs1.next()) { int id = rs1.getInt(1); String name = rs1.getString(2); .... retrieve the other columns using the approriate getXXX() calls } } } if (rs.next()) { // process second ResultSet Object o = rs.getObject(1); if (o instanceof ResultSet) { ResultSet rs2 = (ResultSet)o; while (rs2.next()) { ...... } } } 

psql你也可以使用select * from usp_sel_article_initialdata_new1()你只需要在之后使用FETCH ALL 。 有关示例,请参阅手册: http : //www.postgresql.org/docs/current/static/plpgsql-cursors.html#AEN59018

 postgres=> select * from usp_sel_article_initialdata_new1(); usp_sel_article_initialdata_new1 ----------------------------------   (2 rows) postgres=> fetch all from ""; ?column? ---------- 1 (1 row) postgres=> fetch all from ""; ?column? ---------- 2 (1 row) postgres=> 

(我为上面的例子创建了一个虚函数,它只返回一行,第一个游标的值为1 ,第二个游标的值为2

编辑

为了使其工作,需要在事务内部运行。 因此必须关闭自动提交:

 connection.setAutoCommit(false); 

当我调用存储过程时,我使用EntityManager。 下面我附上简单的例子:

 //StoredProcedureQuery storedProcedure = entityManager.createStoredProcedureQuery("[database_name].[schema_name].[procedure_name]"); StoredProcedureQuery storedProcedure = entityManager.createStoredProcedureQuery("[Mydatabase].[dbo].[process_user]"); //registering INPUT parameters storedProcedure.registerStoredProcedureParameter("Id",Integer.class, ParameterMode.IN); storedProcedure.registerStoredProcedureParameter("Name",String.class, ParameterMode.IN); storedProcedure.registerStoredProcedureParameter("UserType",Integer.class, ParameterMode.IN); //registering OUTPUT parameters storedProcedure.registerStoredProcedureParameter("ErrorCode",Integer.class, ParameterMode.OUT); storedProcedure.registerStoredProcedureParameter("ErrorMessage",String.class, ParameterMode.OUT); //setting INPUT parameters storedProcedure.setParameter("Id", 12345); storedProcedure.setParameter("Name", "Mick"); storedProcedure.setParameter("UserType", 1); //executing procedure storedProcedure.execute(); //getting results Integer errorCode = (Integer) storedProcedure.getOutputParameterValue("ErrorCode"); String errorMessage = (String) storedProcedure.getOutputParameterValue("ErrorMessage"); 

希望这会有所帮助

这在以下版本中对我有用

springframework-version: – 4.2.1.RELEASE

hibernate.version: – 5.0.1.Final

postgresql.version: – 9.1-901-1.jdbc4

 // Call the stored procedure ProcedureCall procedureCall = getSession().createStoredProcedureCall("get_all_matching_email_profile"); // Register the output parameter, postgres support ref_cursor as first parameter only, so don't change it procedureCall.registerParameter(1, void.class, ParameterMode.REF_CURSOR); // Inpur parameters procedureCall.registerParameter(2, BigDecimal.class, ParameterMode.IN); procedureCall.registerParameter(3, String.class, ParameterMode.IN); procedureCall.getParameterRegistration(2).bindValue(companyId); procedureCall.getParameterRegistration(3).bindValue(tempArray[i]); // Execute the procedure and get the result ProcedureOutputs procedureOutputs = procedureCall.getOutputs(); ResultSetOutput resultSetOutput = (ResultSetOutput)procedureOutputs.getCurrent(); List results = resultSetOutput.getResultList(); log.info("The result is "+results.size()); for(Integer j=0;j