Search code examples
javaoraclefunctioncursorcallable-statement

Callabe statement Oracle Update Skip locked fetching out of sequence error


Following is the Function which I am calling using Callabe Statement.Statement fetches a cursor since rowtype is not possible in java.But am getting an error of out of sequence. java.sql.SQLException: ORA-01002: fetch out of sequence

    create or replace FUNCTION DEQUEUE
RETURN SYS_REFCURSOR
IS
  c_Result SYS_REFCURSOR;
BEGIN
  OPEN  c_Result FOR SELECT * FROM QUEUE_SKIP_LOCKED WHERE ROWNUM=1 FOR UPDATE SKIP LOCKED;
declare
  c_fdbQueuerow sys_refcursor;
  l_queueRow QUEUE_SKIP_LOCKED%rowtype;
  begin
  c_fdbQueuerow := c_Result;
loop
    fetch c_fdbQueuerow into l_queueRow;
     IF l_queueRow.key IS NOT NULL THEN
      UPDATE QUEUE_SKIP_LOCKED SET STATUS='WORKING' WHERE KEY=l_queueRow.key;
    END IF;
    exit when c_fdbQueuerow%notfound;
  end loop;
    RETURN c_fdbQueuerow;
end;
  EXCEPTION 
  WHEN OTHERS THEN 
  RAISE;
END dequeue;

Callabe Statement is as follows

session.connection().setAutoCommit(false);
    cs = session.connection().prepareCall("{?=call dequeue}");
    cs.registerOutParameter(1, OracleTypes.CURSOR);
    cs.executeUpdate();
    session.connection().commit();
    ResultSet rs = (ResultSet) cs.getObject(1);
    while(rs.next())

Solution

  • You get the error because the cursor returns one row and that row has already been fetched.

    Do not issue a fetch statement after the last row has been retrieved - there are no more rows to fetch.

    Better split the function into:

    1 A function that returns the ID of the row that has to be updated.

    2 A procedure that does the update

    3 Further processing using the ID.