Ошибка ora 01002 fetch out of sequence

I have a procedure in which I am often getting the following error in oracle 11g:

ORA-01002: fetch out of sequence ORA-06512: 
at "LEAVE.GES_ERP_LEV_FFS_INTERFACE_PRC", line 350 ORA-06512: at line 1.

at line 350 I have-

BEGIN

  FOR V_INTERFACE_EMP IN CUR_INTERFACE_EMP LOOP        (Line 350)
      EXIT WHEN CUR_INTERFACE_EMP%NOTFOUND;
      V_ERR_FLAG  := 'N';
      V_LOCAL_EMP := 'Y';

      BEGIN

The Cursor CUR_INTERFACE_EMP is declared as below

SELECT GELF.*
   FROM GES_ERP_LEV_FFS_INTERFACE_T GELF
 WHERE (GELF.BALANCE_FLAG != 'W' 
         OR GELF.CASE_FLAG = 'S' 
         OR SELF.BALANCE_FLAG IS NULL)
    AND GELF.PROCESS_FLAG = 'N'
    AND GELF.DATE_OF_RELEASE <= TRUNC(SYSDATE);

If i update some records of the table with Process_Flag Y,the batch works fine for some time and then again after some days we get this same issue.

Please help,let me know in case data is also needed for the mentioned table.

Sathyajith Bhat's user avatar

asked Feb 23, 2015 at 7:18

Thepallav_abhi's user avatar

Thepallav_abhiThepallav_abhi

872 gold badges3 silver badges10 bronze badges

1

If i update some records of the table with Process_Flag Y,the batch
works fine for some time and then again after some days we get this
same issue.

You try to fetch from a SELECT FOR UPDATE, however a COMMIT has already been issued before it.

I think you have a COMMIT somewhere INSIDE the LOOP which is causing this issue.

A quote by Tom Kyte here:

for x in ( select rowid rid, t.* from T ) loop
     update T set x = x+1 where rowid = x.rid;
     commit;
  end loop;

That implicit cursor is fetched from «across a commit». It is the
practice of keeping a cursor open after committing. It is a bad
practice and is a common cause of ORA-1555 (the above looping
construct in particular)

Also, you are using a CURSOR FOR LOOP. The CURSOR FOR LOOP will terminate when all of the records in the cursor have been fetched. So, you don’t need to EXIT explicitly.

You could simply do it as:

FOR V_INTERFACE_EMP IN CUR_INTERFACE_EMP 

   LOOP        

     V_ERR_FLAG  := 'N';
     V_LOCAL_EMP := 'Y';
     ...
   END LOOP;

answered Feb 23, 2015 at 7:30

Lalit Kumar B's user avatar

Lalit Kumar BLalit Kumar B

47.3k13 gold badges96 silver badges123 bronze badges

2

I was facing the same issue of fetch out of sequence in oracle plsql.

The problem was below line of code which was used in a procedure that was getting called from inside the loop.

————-problem code———
if p_ret is null
then
p_ret := ‘SUCCESS’;
rollback;
return;
end if;

————-problem code———

I should not have used rollback.

So, watch out for rollback and commit inside the loop statement.

answered Aug 3, 2021 at 12:23

Anish kumar singh's user avatar

I am getting org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL

UPDATE responses 
SET    version_no = ( version_no + 1 ), 
       read_status = 0, 
       tslastmodified = SYSDATE 
WHERE  responseid IN (SELECT responseid 
                      FROM   responses 
                      WHERE  read_status = 1 
                             AND tslastmodified < SYSDATE - 45 / ( 24 * 60 ) 
                             AND id IN (SELECT id 
                                        FROM   emp)) 

; SQL state [24000]; error code [1002]; ORA-01002: fetch out of sequence
; nested exception is java.sql.SQLException: ORA-01002: fetch out of sequence

JAVA code :

getJdbcTemplate().queryForObject(SurveyQuery.UPDATE_INPROCESS, Integer.class);

Please let me know what is wrong in above query

Lalit Kumar B's user avatar

Lalit Kumar B

47.3k13 gold badges96 silver badges123 bronze badges

asked Nov 3, 2014 at 4:44

yusuf's user avatar

You can modify your UPDATE statement to something like below

UPDATE RESPONSES SET VERSION_NO=(VERSION_NO+1), 
READ_STATUS=0, 
TSLASTMODIFIED = SYSDATE 
WHERE READ_STATUS = 1 
AND TSLASTMODIFIED < SYSDATE - 45/(24*60) 
AND EXISTS (SELECT 1 FROM EMP
            WHERE RESPONSES.ID = EMP.ID)

Note: Though you can use the above modified query but I doubt the said error is because of the posted update statement. From Documentation it looks like the cause of the above error could be

When you perform a FETCH on an active cursor after all records have
been fetched.

(OR)

When you perform a FETCH on a SELECT FOR UPDATE after a COMMIT has
been issued.

answered Nov 3, 2014 at 5:16

Rahul's user avatar

RahulRahul

75.9k13 gold badges70 silver badges124 bronze badges

4

totn Oracle Error Messages


Learn the cause and how to resolve the ORA-01002 error message in Oracle.

Description

When you encounter an ORA-01002 error, the following error message will appear:

  • ORA-01002: fetch out of sequence

Cause

You tried to perform a FETCH at a time when it is not allowed.

Resolution

The option(s) to resolve this Oracle error are:

Option #1

This error may occur if you perform a FETCH on an active cursor after all records have been fetched.

Option #2

This error may also occur if you perform a FETCH on a SELECT FOR UPDATE after a COMMIT has been issued.

You may want to consider utilizing cursor attributes to avoid these situations.

ORA-01002

ORA-01002: выборка вне последовательности

Причина:

В программе основного языка, FETCH вызов исходит вне последовательности. Вызов должен выполняться перед выборкой.

Действие:

Проанализируйте и выполните SQL оператор перед попыткой сделать выборку данных.

Avatar of kretzschmar

kretzschmar

Flag for Germany asked on 6/20/2002

what causes this error?
how to avoid this error?

first in general,
later i may describe a detailed problem

meikl ;-)

Oracle Database

Avatar of undefined

The Oracle documentation says this happens only (or at least mainly) in 3-GL programs that use OCI to interact with Oracle and only if they attempt to «fetch» either before opening a cursor or after closing it.

I have seen this error at times in PLSQL blocks and SQR programs.  Sometimes it is true, that the program attempted a fetch before opening a cursor or after closing it.  Other times though, the code looked correct.

Another situation that seems to cause this sometimes (but certianly not always) is with a commit inside of a cursor loop.  PLSQL cursors that fetch records via a database link seem to get this error more often.

Hi,

one bad example can be:

declare
cursor c is select dummy from dual for update;
str dual.dummy%type;
begin
 open c;
 loop
  exit when c%notfound;
  fetch c into str;
  commit;
 end loop;
 close c;
end;

another bad one which causes the same problem is:

declare
begin
 for c in (select dummy from dual for update) loop
  commit;
 end loop;
end;

NOTE:
avoid them by good programming, NO COMMIT inside fetching a cursor which contains FOR UPDATE clause.

best regards,
Marius Nicoras

well,
thanks for your responses,
sorry for delay, i had to sleep ;-)

now to the problem,
which does not fit to your comments

simplified sample

….
  type t_cursor is ref cursor;
  v_cursor t_cursor;
….

  v_statement := ‘SELECT  rowid’||
                 ‘ FROM ‘||pi_tabelle||
                 ‘ WHERE fieldname = :pi_parameter’;
  open v_cursor for v_statement using in pi_parameter;
  loop
    fetch v_cursor into v_rowid;
    exit when v_cursor%notfound;
    call_a_customizeable_workprocess(v_rowid);
  end loop;

     
in the
  call_a_customizeable_workprocess(v_rowid);
are primary dynamic-sql dmls and dynamic package-procedure calls with commits and rollbacks

the cursor self runs over tenthousends-records,
the dmls affects over 10 tables with inserts and updates,
so that i cannot not
avoid a commit/rollback within the loop because

-the rollback-segement becomes to small
-there may some asynchronous calls, which needs commited data

as stated, there is no for update clause
and all is pure pl/sql-coded, no database-link

the fitting part is this line of markgeers comment
>situation that seems to cause this sometimes (but
>certianly not always) is with a commit inside of a cursor
>loop

the question is why does this happen (sometimes),
because it is not documented (i found nothing)
and how to avoid this

meikl ;-)

are you getting this error allways or just sometimes?
i found this in docs (well, it’s from 8i, but maybe it helps): «This [ORA-01002] can occur if an attempt was made to FETCH from an active set after all records have been fetched.»
so, looks like that instead of returning NO_DATA_FOUND sometimes oracle returns ORA-01002.maybe you have a loop somewhere in call_a_customizeable_workprocess that doesn’t have a exit when cursor%notfound? or maybe you handle NO_DATA_FOUND with exeption when NO_DATA_FOUND?

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.

View this solution by signing up for a free trial.

Members can start a

7-Day free trial

and enjoy unlimited access to the platform.

to 333

using oreacle 8.1.7

>maybe you have a loop somewhere in
>call_a_customizeable_workprocess that doesn’t have a exit
>when cursor%notfound?

no

>maybe you handle NO_DATA_FOUND with exeption when
>NO_DATA_FOUND

no

>Cursors are supposed to become invalid at the end of a
>transaction (ANSI standard) — and the rollback/commit
>ends the transaction.

sounds logical, but some thousends records are
commited/rollbacked until this error comes up,
which should not work, if this would true

meikl ;-)

>of the bind variable has been changed
the bindvariables remains static until the cursor is closed

have you read the doc on metalink?
here’s a little bit more from it:
«Oracle has alway been overgenerous by failing to
invalidate cursors — so code can be written which
commits, or rolls back, in the middle of a cursor
loop. However, such code may fail in a completely
random way — you say that you haven’t observed a
failure if you replace the ROLLBACK with a COMMIT —
if you search the archive you will find that this
is just luck on your part, other users have complained
of exactly this problem in the past when using a
commit in a cursor loop.

You should always code on the assume that every
cursor becomes invalid on rollback/commit — or
write your code to trap the inevitable, but
unpredictable, 1002 error.»

so you may get this error after few fetches, after thousand fetches or you may not get this error at all (if you’re lucky) :)
anyway, i think that autonomous transactions may help here

hmm,
in this case,
there must be a
lot of lucky coders,
because i saw a lot of code
from others, which do such

for example, i know a routine
which loops about millions of records
of a table and transports some data
to another table (updates).
each 1000 record is done a commit.

there is no problem and
no autonomous transaction

about metalink, i’ve no account there

meikl ;-)

me too never had such error (lucky me :), but as stated above, you may don’t get this error (as most people do) or you may get it.
once i wrote a program that selects from few tables and inserts into other few tables. there wasn’t millions of records, only about 100000. i used bulk inserts/collects and sometimes i get «end of file on communication channel» :)
of course, noone else had such error ….

it just proves, that any case is unique ;)

if you’re intrested, i can post article from metalink here.

hmm,

sounds like,
if i want to by an airplane,
the constructor explains me,
sometimes the plane breaks in air,
didn’t know why,
maybe because its heavier than air,
but mostly you can fly and land properly.

i would not fly with this plane.

>if you’re intrested,
>i can post article from metalink here.

would be nice, if it is a long article,
then you could send it to me via eMail
to info@meikl.de

meikl ;-)

i’ve sent article to you.
it’s ANSI standard that after transaction ends, all cursors for this transaction should be invalidated. oracle tries to overcome such limitation, but sometimes it doesn’t work :)
i saw such error first time, and all the time i was sure that you may freely commit/rollback transaction in cursor loop (simple loop, not FOR UPDATE one) without any problems. well… now i don’t know what to think :o

There’s interesting (and hopefully helpful) information in some of these comments.  I guess I’ve usually been fortunate too with commits inside a cursor loop.  Often that is the only (or at least the easiest) way to get a job done that involves processing lots of rows.

Yes, autonomous transactions may be able to help you, but be careful with them.  Make sure you do not use them with database links (distributed transactions).  Unfortunately Oracle does not support that combination, and you may get strange errors or unpredictably failures if you try it.

333,

thanks for the article

the artice indicates,
that there is a «bug» with
oracle version 8.1.7, when a
rollback in a loop is done.

commits seems not to be the problem.

i will check this on monday,
and if i can confirm this,
then i can code a workaround,
and you gets the points, 333

i’ve raised the points up to 150

markgeer, mnicoras,
i will post, after my check at next monday,
50 pts questions for you both
for your in general comments.

in conclusion,
i’m to 99% sure that a rollback in
a cursor-loop
causes this error
on an oracle 8.1.7 server

in the meantime
have a nice weekend

meikl ;-)

well, article says that commit may cause this error also.  so 1% for commit :)

yep,
1% for commit,
because commit seems to be only a problem,
if a for update-clause is given

meikl ;-)

Hi,

sorry to bother but the following example is your problem …

declare
begin
for c in (select rowid,dummy from dual for update) loop
 commit;
end loop;
end;

looks like the problem is that somehow you will update the record set you have selected …

I’m right?

it’s not a bug as I see, it’s just a case when it happens in your plsql code to update the result set …

best regards,
Marius Nicoras

ps: I had to sleep also … :-)

just for clarify, Marius,

there is definitivly NO for update-clause
by the problem described above

sure would a cursor with a for update-clause
with a commit in the loop
cause the ora-01002 exception,
in all oracle-server versions,
i guess

meikl ;-)

:-( couldn’t reproduce this problem with following sample

declare
  type t_cursor is ref cursor;
  —cursor v_cursor is
  —select sendungs_id from sendungen;
  v_count number := 0;
  dummy atable.id%TYPE;
  v_cursor t_cursor;
begin
  dbms_output.put_line(‘First Loop->Inserts’);
  open v_cursor for ‘select id from atable’;
  loop
    fetch v_cursor into dummy;
    exit when v_cursor%NOTFOUND;
    insert into mk_text (ID) values (dummy);
    v_count := v_count + 1;
    if (mod(v_count,1000) = 0) then
      dbms_output.put_line(‘Before Rollback’);
      rollback;
    else
      commit;
    end if;
  end loop;
  close v_cursor;

  dbms_output.put_line(‘Second Loop->Updates’);
  v_count := 0;
  open v_cursor for ‘select id from mk_text order by flag desc’;
  loop
    fetch v_cursor into dummy;
    exit when v_cursor%NOTFOUND;
    execute immediate ‘update mk_text set flag = »X» where id = :dummy’ using in dummy;
    v_count := v_count + 1;
    if (mod(v_count,1000) = 0) then
      dbms_output.put_line(‘Before Rollback’);
      rollback;
    else
      commit;
    end if;
  end loop;
  close v_cursor;

exception
  when others then
    if v_cursor%ISOPEN then
      close v_cursor;
    end if;
    dbms_output.put_line(substr(sqlerrm,1,250));
END;

 

this code runs about 35000 records,
each record is commited, each 1000th
record is rollbacked,
in both loops

runs fine, which is just not this what i had expected :-(

searching further, take this just as an info

meikl ;-)

you should try something like:


begin
— transaction starts   insert into atable (id) values (23456);   open c for ‘select id from atable’;
   loop
      fetch c into dummy;
      exit when c%NOTFOUND;
      if dummy=100 then
— transaction ends;
         rollback;      end if;
   end loop;
— transaction ends;
   commit;
end;
so, as you see, your cursor should fetch new inserted value, but after rollback this value will gone (dunno where :) and you get fetch out of sequence.
i didn’t tested this example, will try it for myself later.

hehe,
yes, this i would understand, 333,
but such a configuration isn’t given
by my problem->threetimes checked

meikl ;-)

well,

autonomous transaction solves this problem,
even if i don’t know what this error causes,
nor that it is not so simple to reproduce.

thanks for your help 333

markgeer, mnicoras,
watch out for your points

meikl ;-)

When I ran into this problem, the solution was to turn off autocommit and then do an explicit commit after each update:
         conn.setAutoCommit(false);

         conn.commit();

I just want to add that gshifrin’s solution, setting autocommit off, worked for me.

grtz Gstarr

  • Ошибка ora 00936 отсутствует выражение
  • Ошибка ora 00920 invalid relational operator
  • Ошибка ora 00054 resource busy and acquire with nowait specified or timeout expired
  • Ошибка ora 00001 unique constraint violated
  • Ошибка or tapsh 08 при добавлении карты гугл pay