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.
asked Feb 23, 2015 at 7:18
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 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
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
47.3k13 gold badges96 silver badges123 bronze badges
asked Nov 3, 2014 at 4:44
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
RahulRahul
75.9k13 gold badges70 silver badges124 bronze badges
4
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 оператор перед попыткой сделать выборку данных.
kretzschmar
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
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
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