In the below example , I have a SP which will return a SYS_REFCURSOR as OUT parameter to the Java service, and in the same SP it will insert the SYS_REFCURSOR result to another table example -temp. When I execute the SP, it gives an error
ORA-01002 : fetch out of sequence error
I do see the data getting inserted but the service is not returning back any REFCURSOR to the service.
create or replace procedure ins_act(l_result OUT sys_refcursor)
as
--Created a RECORD type to hold the result of the SYS_REFCURSOR
TYPE RSLT IS RECORD
(
l_id1 varchar2(32),
l_id2 varchar2(32),
l_id3 varchar2(32),
l_pid varchar2(16),
l_ac varchar2(32),
l_activity_date varchar2(32),
l_file_id varchar2(64)
) ;
--Created associative array to hold the result
Type v_reslt is table of RSLT index by PLS_INETEGER;
--Variable to Record type
var_reslt v_reslt;
begin
-- Procedure to pull the get records
OPEN l_result FOR
SELECT COL1,COL2,COL3,CoUnt(*).....
-- Bulk fetch
Loop
fetch l_result bulk collect into var_reslt limit 100;
--Bulk Insert
FORALL I INTO 1..var_reslt.count SAVE EXCEPTIONS
insert into temp(id1,
id2,
id3,
platform_id,
activity_code,
update_timestamp,
file_id)
values
(to_char(to_date(var_reslt(i).l_id1,'mm/dd/yyyy'),'mm/dd/yyyy'),
var_reslt(i).l_id2,
var_reslt(i).l_id3,
0,
var_reslt(i).l_ac,
var_reslt(i).l_activity_date,
var_reslt(i).l_file_id);
exit when l_result%notfound;
end loop;
Commit;
close l_result;
Exception
WHEN OTHERS
THEN
--Bulk Exception handling
FOR indx IN 1 .. SQL%BULK_EXCEPTIONS.COUNT
LOOP
DBMS_OUTPUT.put_line (
SQL%BULK_EXCEPTIONS (indx).ERROR_INDEX
|| ‘: ‘
|| SQL%BULK_EXCEPTIONS (indx).ERROR_CODE);
RAISE;
end;
/
Several problems with this code.
The first is that you are checking whether the cursor found anything after the FORALL statement. This is wrong because the FORALL statement attempts to process the cursor even when the cursor is
%notfound
. That might be the source of your ORA-01002 exception.The second error is a subtle one. Checking for cursor
%notfound
is a problem with LIMIT clause, because it will evaluates totrue
when the cursor returns any number of records less than the limit: it will be%notfound
even if the cursor returns 99 records. This is a non-intuitive aspect of the PL/SQL implementation. Anyway, it is better to check the number of entries in the collection.Here is your code fixed for these two issues:
The final error is procedural. A refcursor is a one-time shot. You read it in the program, which means it is exhausted when you pass it back to the java layer. There are a couple of ways to resolve this, depending on what exactly you're trying to achieve. Post more details regarding your logic.