1

需要访问从 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;

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

4

5 回答 5

3

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

以下对我有用:

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
----------------------------------
 <unnamed portal 1>
 <unnamed portal 2>
(2 rows)

postgres=> fetch all from "<unnamed portal 1>";
 ?column?
----------
        1
(1 row)

postgres=> fetch all from "<unnamed portal 2>";
 ?column?
----------
        2
(1 row)

postgres=>

(我为上面的示例创建了一个虚拟函数,它只返回一行,其中包含1第一个游标和2第二个游标的值)

编辑

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

connection.setAutoCommit(false);
于 2014-09-08T09:03:35.943 回答
0

当我调用存储过程时,我使用 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");

希望这会有所帮助

于 2014-09-08T08:24:50.653 回答
0

这在以下版本中对我有用

springframework 版本:- 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<results.size();j++) {
Object[] objects = (Object[]) results.get(j);
log.info("The result is "+objects.length);
 }
于 2015-12-09T05:36:09.053 回答
0

这对我有用:

Connection conn = DBConnection.getNMSDBConnection();    
            conn.setAutoCommit(false);
             CallableStatement properCase = conn.prepareCall("{ ? = call data.temperature_raw_data( ?,?,?,? ) }") ;
                 properCase.registerOutParameter(1, Types.REF_CURSOR);
                 properCase.setLong(2, startDate);
                 properCase.setLong(3, endDate);
                 properCase.setString(4, deviceIp);
                 properCase.setString(5, customers);
                 properCase.execute();
                ResultSet rs = (ResultSet) properCase.getObject(1);
                while (rs.next()) 
                {
                    HashMap<String, Object> record = new HashMap<>();                       
                    record.put("date", rs.getTimestamp(1));
                    record.put("nodeIp", rs.getString(2));
                    record.put("avg", rs.getDouble(3));
                    records.add(record);
                }
于 2020-05-07T13:09:45.150 回答
0
if you want to write a java code which will call PostgreSQL Stored procedure where 
there is an INOUT refcursor.
PostgreSQL SP:

 CREATE OR REPLACE PROCEDURE  Read_DataDetails(INOUT  my_cursor REFCURSOR = 'rs_resultone')
 LANGUAGE plpgsql
 AS $$                                                    
 BEGIN
 OPEN my_cursor FOR Select * from MyData;      
 END;
 $$;

 corresponding java code will be:

connection = getConnection(your connection parameter);
if (connection != null) {
connection.setAutoCommit(false); // This line must be written just after the 
//connection open otherwise it will not work since cursor will be closed immediately. 
String readMetaData = "CALL Read_DataDetails(?)";
callableStatement = connection.prepareCall(readMetaData);
callableStatement.registerOutParameter(1, Types.REF_CURSOR);
callableStatement.execute();
rs = (ResultSet) callableStatement.getObject(1);
if (rs != null) {
    while (rs.next()) {
                 <Your Logic>
                }//end while
            }//end if

}//end if
于 2020-06-18T12:42:28.950 回答