ORACLE SQL%ROWCOUNT doesn't work inside a cursor fetch - oracle

In my following code, I'm unable to get the inserted row count within a cursor fetch.
...
row_count NUMBER:= 0;
BEGIN
OPEN object_id_cur(id, c_bool);
LOOP
FETCH object_id_cur INTO l_object_id;
EXIT WHEN object_id_cur%NOTFOUND;
INSERT INTO table1(
id,
num
)
SELECT t2.r_object_id,
t2.num
FROM table2
WHERE t2.r_object_id = l_object_id.r_object_id;
row_count:= row_count + SQL%ROWCOUNT;
-- I also tried dbms_output.put_line(SQL%ROWCOUNT);
END LOOP;
CLOSE object_id_cur;
COMMIT;
dbms_output.put_line('insert count= ' || row_count || ' rows inserted...');
END;
My obtained result is: count = rows inserted... count is blank. If I move the insert outside the cursor fetch, then the row count works just fine. Is there a logical explanation for this? Thanks!

count is a reserved keyword. Use "count" or some other identifer say cnt. Also, add the missing semicolon at then end of the increment statement.
declare
cnt number := 0;
begin
. . .
cnt := cnt + SQL%ROWCOUNT;
. . .
Demo:
SQL> create table t (id int);
Table created.
SQL> declare
2 cursor c is
3 select level n from dual connect by level <= 100; -- produces 100 rows
4 n int;
5 cnt number := 0;
6 begin
7 open c;
8 loop
9 fetch c into n;
10 exit when c%notfound;
11 insert into t (id)
12 select n from dual union all
13 select n from dual; -- insert each value twice
14 cnt := cnt + sql%rowcount;
15 end loop;
16 close c;
17 dbms_output.put_line(cnt); -- should be 200
18 end;
19 /
200 -- correct output
PL/SQL procedure successfully completed.
SQL>
As you can see above, the SQL%rowcount works correctly. It could be that your below select query is not producing any rows.
SELECT t2.r_object_id,
t2.num
FROM table2
WHERE t2.r_object_id = l_object_id.r_object_id;

SQL%ROWCOUNT return the number of rows fetched/processed by the last DML executed. If the DML fails after fetching 1 row, due to any reason, SQL%ROWCOUNT will return only 1, the number of rows fetched/processed so far. It wont give you the total count. I did a simple PLSQL block and getting the SQL%ROWCOUNT working fine. Seems there is something else which is not working in your code.
declare
num number := 0;
begin
for i in 1 .. 10
loop
insert into a_table (id)
values (i);
num := num + sql%rowcount;
end loop;
dbms_output.put_line (num);
end;

Related

'ORA-01002 fetch out of sequence' when fetching from cursor based on truncated temporary table

I have a PLSQL function which opens new cursor based on join of persistent table with temporary table. Every time the new cursor is created, the temporary table is truncated and filled with data (the content of temporary table is subset of ids in persistent table - it is actually result of computation of complex search query), each in own autonomous transaction.
Let's create two cursors. First cursor reads half of data, then second cursor reads all data and closes, then the first cursor tries to read remaining data. The attempt of reading remaining data fails with ORA-01002 fetch out of sequence error. The wrong behaviour is observed on Oracle 19.0.0.0.0 (our db) and 19.14.0.0.0 (LiveSQL) but not on Oracle 11 (our previous version).
Minimized example:
create global temporary table temp_table (
id number(38,0)
) on commit preserve rows;
create table data_table (
id number(38,0),
val varchar2(10)
);
insert into data_table
select 1, 'a' from dual union all
select 2, 'b' from dual union all
select 3, 'c' from dual union all
select 4, 'd' from dual;
declare
type ref_cursor is ref cursor;
procedure storeToTempTable
is
cmd varchar2(32767);
pragma autonomous_transaction;
begin
cmd := q'[
insert into temp_table (id)
select 1 from dual union all
select 2 from dual union all
select 3 from dual union all
select 4 from dual
]';
execute immediate cmd;
commit;
end;
procedure truncateTempTable
is
pragma autonomous_transaction;
begin
execute immediate 'truncate table temp_table';
end;
function getCursor return ref_cursor
is
cur ref_cursor;
q varchar2(32767);
begin
truncateTempTable;
storeToTempTable;
q := 'select r.* from data_table r, temp_table t where r.id = t.id';
open cur for q;
return cur;
end;
--------------------------------------------------------------------------------
begin -- main
declare
cursor1 ref_cursor;
cursor2 ref_cursor;
dto data_table%rowtype;
i1 pls_integer := 0;
i2 pls_integer := 0;
begin
cursor1 := getCursor;
loop
exit when i1 = 2;
i1 := i1 + 1;
fetch cursor1 into dto;
exit when cursor1%notfound;
dbms_output.put_line('i1 = ' || i1 || ', dto.id = ' || dto.id);
end loop;
dbms_output.put_line('not closing 1');
--dont close cursor1;
cursor2 := getCursor;
loop
i2 := i2 + 1;
fetch cursor2 into dto;
exit when cursor2%notfound;
dbms_output.put_line('i2 = ' || i2 || ', dto.id = ' || dto.id);
end loop;
dbms_output.put_line('closing 2');
close cursor2;
loop
i1 := i1 + 1;
fetch cursor1 into dto;
exit when cursor1%notfound;
dbms_output.put_line('i1 = ' || i1 || ', dto.id = ' || dto.id);
end loop;
dbms_output.put_line('closing 1');
close cursor1;
end;
end;
/
I guess the table truncation somehow invalidates cursor1 during creation of cursor2. I don't have a clue why this worked in previous version (I actually wonder it worked.)
I also figured out a workaround - to replace body of truncateTempTable procedure for execute immediate 'delete from temp_table'; commit;. (Commit is necessary, otherwise ORA-06519 appears.) With the workaround, scripts provides correct result:
Table created.
Table created.
4 row(s) inserted.
Statement processed.
i1 = 1, dto.id = 1
i1 = 2, dto.id = 2
not closing 1
i2 = 1, dto.id = 1
i2 = 2, dto.id = 2
i2 = 3, dto.id = 3
i2 = 4, dto.id = 4
closing 2
i1 = 3, dto.id = 3
i1 = 4, dto.id = 4
closing 1
My question is if there is some support in documentation for such behavior and correctness of proposed workaround.
LiveSQL demo here. (no dbfiddle, sorry - attempts on 18c either fail or return even different results)

arrays in pl sql | varray | associative

I'm planning to write a pl sql
pseudo code
procedure a gets all records from emp and is passed to procedure b
procedure b getting called inside from a , is transforming the data from emp , each emp record is traversed 6 times and storing the data in an array
inside procedure b , i used varray (size of 2000 to 2 mil) and also associative array , but it is always failing after handling 10 -15 records .i.e. after handling it for 60 -90 records
i am reusing the same index for storing my data but nothing worked i.e. 1 to 6
I am not sure what i am doing wrong , please assist .
create or replace PROCEDURE query_emp ( bill_cycle_ip in number,
no_of_recs in number ) AS
TYPE billAcnt IS REF CURSOR RETURN emp%ROWTYPE;
ba_rec emp%ROWTYPE;
b_a billAcnt;
total_num_of_rec number ;
BEGIN
OPEN b_a FOR
select * from
(select * from emp where bill_cycle =1 and ban_status in ('O' ,'S')
union
select * from emp where bill_cycle =1 and ban_status in ('N')
and STATUS_LAST_DATE >= sysdate -30
)
where ban not in (Select ban from temp_ba)
and rownum <no_of_recs;
LOOP
FETCH b_a INTO ba_rec;
EXIT WHEN b_a%NOTFOUND;
create_final_snapshot (ba_rec);
END LOOP;
CLOSE b_a;
END;
create or replace procedure create_final_snapshot ( ba_rec IN emp%ROWTYPE ) AS
cur_bl_seq_number number ;
bl_seq_number_minus_six number ;
type total_due_amt is table of number INDEX BY PLS_INTEGER ;
nt total_due_amt := total_due_amt();
b number := 1 ;
BEGIN
cur_bl_seq_number :=ba_rec.BL_CUR_BILL_SEQ_NO ;
if ba_rec.BL_CUR_BILL_SEQ_NO-5 <=1 then
bl_seq_number_minus_six:=1;
else
bl_seq_number_minus_six:=ba_rec.BL_CUR_BILL_SEQ_NO-5;
end if ;
for a in bl_seq_number_minus_six..cur_bl_seq_number
LOOP
--nt.extend();
select xyz into nt(b) from emp_2 where ban =ba_rec.ban and bill_seq_no =a ;
dbms_output.put_line('total_due_amt_list sun= ' ||ba_rec.ban ||' ' || nt(b) || ' bill seq no ' ||a ||' b ' || b );
b := b +1;
END loop;
b:=1;
insert into temp_ba
values (nt(1) ,nt(2), nt(3),nt(4),nt(5),nt(6) );
END;

oracle delete data from table with rownum

I have a procedure that deletes the data from table1. Five instances of the procedure running the same time and all ran without any error/exception.
But still, there are many records in the table1 where EndTime <= v_purgedate. Please help.
declare
rowcount1 NUMBER;
begin
LOOP
delete table1 eh
where eh.EndTime <= v_purgedate
and rownum <= 30000 ;
rowcount1 := rowcount1 + sql%rowcount;
commit;
exit when rowcount1=0;
rowcount1=0;
END LOOP;
end;
/
You are trying to do what is called "do it yourself parallelism", as opposed to the parallel processing that Oracle can do by itself if you ask nicely.
There is a package called DBMS_PARALLEL_EXECUTE that does this for you. You split the data into chunks (based on ROWIDs or numbers), then call the RUN_TASK procedure to process each chunk, either serially or in parallel. There is one commit per chunk.
Here is a demonstration that deletes 30,000 rows per commit. First, test data:
SQL> create table table1(endtime) as
2 select trunc(sysdate) - level/24 from dual
3 connect by level <= 240000;
Table TABLE1 created.
SQL> insert into table1 select * from table1;
240,000 rows inserted.
SQL> insert into table1 select * from table1;
480,000 rows inserted.
SQL> insert into table1 select * from table1;
960,000 rows inserted.
SQL> select count(*) from table1;
COUNT(*)
----------
1920000
Now, here is the code:
SQL> declare
2 l_task_name varchar2(128) := 'Delete_TABLE1';
3 l_sql_chunk clob := q'§
4 select date '2100-01-01' - min(endtime) start_id,
5 date '2100-01-01' - max(endtime) end_id,
6 chunk
7 from (
8 select endtime,
9 ceil(row_number() over(order by endtime) / 30000) chunk
10 from table1 where endtime < sysdate - 8000
11 )
12 group by chunk
13 §';
14 l_sql_run clob := q'§
15 delete from table1
16 where endtime between
17 date '2100-01-01' - :start_id and
18 date '2100-01-01' - :end_id
19 §';
20 l_boolean boolean := false;
21 task_not_found EXCEPTION;
22 PRAGMA EXCEPTION_INIT(task_not_found, -29498);
23 begin
24 begin
25 DBMS_PARALLEL_EXECUTE.DROP_TASK (l_task_name);
26 exception when task_not_found then null;
27 end;
28 DBMS_PARALLEL_EXECUTE.CREATE_TASK (l_task_name);
29 DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_SQL (
30 task_name => l_task_name,
31 sql_stmt => l_sql_chunk,
32 by_rowid => l_boolean
33 );
34 DBMS_PARALLEL_EXECUTE.RUN_TASK (
35 task_name => l_task_name,
36 sql_stmt => l_sql_run,
37 language_flag => 1,
38 parallel_level => 0 -- 0 for serial, 2+ for parallel
39 );
40 end;
41 /
you have an endless Loop, because rowcount1 will never be 0 when your table contains data that will be deleted.
i think what you what is
declare
rowcount1 NUMBER;
begin
LOOP
delete table1 eh
where eh.EndTime <= v_purgedate -- you should also initialize a variable
and rownum <= 30000 ;
--rowcount1 := rowcount1 + sql%rowcount;
commit;
exit when sql%rowcount = 0;
rowcount1=0;
END LOOP;
end;
/
When you declare the variable rowcount1, you do not assign any number to it, so its value is NULL. Afterwards, when you add a number to NULL the result is always NULL. This is surely not what you want. To illustrate:
SQL> declare
2 rowcount1 NUMBER;
3 begin
4 dbms_output.put_line('<'||rowcount1||'>');
5 rowcount1 := rowcount1 + 1;
6 dbms_output.put_line('<'||rowcount1||'>');
7 end;
8 /
<>
<>
PL/SQL procedure successfully completed.
It seems your code will go in an endless loop. You say that is not the case, so clearly you are not showing us any real code.
Anyway, this is not a good way to do what you want. I'll post another answer saying why.
Regards, Stew Ashton
It's a easy code for delete data in a table .
Try it.
declare
cursor c is
select * from table1 where rownum<=30000;
begin
for i in c loop
delete from table1 where EndTime <= v_purgedate;
end loop;
commit;
end;

Bulk insert using FORALL in Oracle

I am currently using the following code to do a bulk insert of 50 million rows:
declare cnt number;
BEGIN
select max(run_ver_issue_id) into cnt from "ABHINAV"."MV_RUN_VER_ISSUE";
FOR x IN 1 .. 50000000 LOOP
INSERT INTO "ABHINAV"."MV_RUN_VER_ISSUE" NOLOGGING ("RUN_VER_ISSUE_ID","CUST_ISSUE_ID","TITLE","ORIGINAL_ISSUE_ID","SOURCE_FILE_LINE","DISPLAY_TEXT","RUN_VER_ID","SANDBOX_SRC_FILE_ID","ACCOUNT_ID","ISSUE_STATE","CURRENT_SEVERITY","INSERT_TS","MODIFIED_TS","CWE_ID","TEMPLATE_FILE_ID","TEMPLATE_FILE_LINE","CURRENT_EXPLOIT_LEVEL","CNT","SOURCE_FUNCTION_PROTOTYPE","SOURCE_RELATIVE_LOCATION","SOURCE_SCOPE","PROCEDURE_NAME","PROCEDURE_HASH","PROTOTYPE_HASH","STATEMENT_HASH","STATEMENT_HASH_COUNT","STATEMENT_HASH_ORDINAL","SUBMODULE_PATH") VALUES (x+cnt,2,..);
END LOOP;
END;
It takes almost 6 hours it to finish. The table does have an index on RUN_VER_ISSUE_ID, but still doesn't help. I tried using FORALL, getting an error PLS-00430: FORALL iteration variable X is not allowed in this context for the below code:
declare cnt number;
BEGIN
select max(run_ver_issue_id) into cnt from "ABHINAV"."MV_RUN_VER_ISSUE";
FORALL x IN 1 .. 5
INSERT INTO "ABHINAV"."MV_RUN_VER_ISSUE" NOLOGGING ("RUN_VER_ISSUE_ID","CUST_ISSUE_ID","TITLE","ORIGINAL_ISSUE_ID","SOURCE_FILE_LINE","DISPLAY_TEXT","RUN_VER_ID","SANDBOX_SRC_FILE_ID","ACCOUNT_ID","ISSUE_STATE","CURRENT_SEVERITY","INSERT_TS","MODIFIED_TS","CWE_ID","TEMPLATE_FILE_ID","TEMPLATE_FILE_LINE","CURRENT_EXPLOIT_LEVEL","CNT","SOURCE_FUNCTION_PROTOTYPE","SOURCE_RELATIVE_LOCATION","SOURCE_SCOPE","PROCEDURE_NAME","PROCEDURE_HASH","PROTOTYPE_HASH","STATEMENT_HASH","STATEMENT_HASH_COUNT","STATEMENT_HASH_ORDINAL","SUBMODULE_PATH") VALUES (x+cnt,2,.....);
END;
I would request you to please provide your suggestions and comments as to how I can speed this up.
you may use this:
declare
p_array_size number := 100000;
type array is table of number;
l_data ARRAY;
cursor c is select rownum seq_no from dual connect by rownum <= p_array_size;
cnt number;
begin
open c;
loop
select max(RUN_VER_ISSUE_ID) into cnt from "ABHINAV"."MV_RUN_VER_ISSUE";
fetch c bulk collect into l_data limit p_array_size;
forall x IN 1 .. l_data.count
insert into "ABHINAV"."MV_RUN_VER_ISSUE"("RUN_VER_ISSUE_ID","CUST_ISSUE_ID","TITLE","ORIGINAL_ISSUE_ID","SOURCE_FILE_LINE","DISPLAY_TEXT","RUN_VER_ID","SANDBOX_SRC_FILE_ID","ACCOUNT_ID","ISSUE_STATE","CURRENT_SEVERITY","INSERT_TS","MODIFIED_TS","CWE_ID","TEMPLATE_FILE_ID","TEMPLATE_FILE_LINE","CURRENT_EXPLOIT_LEVEL","CNT","SOURCE_FUNCTION_PROTOTYPE","SOURCE_RELATIVE_LOCATION","SOURCE_SCOPE","PROCEDURE_NAME","PROCEDURE_HASH","PROTOTYPE_HASH","STATEMENT_HASH","STATEMENT_HASH_COUNT","STATEMENT_HASH_ORDINAL","SUBMODULE_PATH")
values(l_data(x)+cnt,2,'0pJDFy1viDnN2Ku66XPl458gKakF4xz4pTawwoOZYCt0yR2YOw7tH1Mk3oKQ7ynuyasbBjBXr1teBbBdmIsJReIM3kbzWY7H4c6CVgVaw',NULL,230969,'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',74228,2,6120,8096,581270,'26-Sep-12 01:30:00','21-Feb-00 03:52:00',7531,1,NULL,5203,12726,'NAxr4jgRDRnDJiNKp10sfdntA8MKBU0xwWEInpm4yOTjvj5aRHt4fcNujL777cw74AuLEeEskCgzbkZNk2fcaTpBmYl8GtrUsB7KH5Wtfb4Elo8tfpRD7Eh7CjjkTdke7opjX5IBBEDSlxyinbcSLrtK7FuOBXDWM0tMGuq86VlZc27obCFBJyFSGi5FFgAA0PWETUoDR7HerxaisVUzmWuAb1HTKHgdTucNFzvtsxcCXKBwlpE3I7S8G2rhEGs2KOajFOoiB7ZbTPOFSNh7qUEY83GowgJo2lDChWr5tCtQqeJGUyrA2e8kXQ3Oh8Ov28C6muKtSbQFLFrJ0WlQYnDBvXqrHes0wT8rkHMEedJ1NIrf2HBBbI06p2qlO7RCr878gngE3bPiocJAvNHJfnkwnDMu06wda3ZkMmXBL1HTfdPyWfcL44OHzPsQdD4yr6HiM8vP7bzzxXNMBWDuDim8oeAc6o1jByEzgzyztvX6mas4UxAXG4Hm8iWodaoYwUixaFw4vr8qpp7jp8HfYbgC7J6pH4PQKV8krjvGdW3o33tHHBFS6Ytxobi31iSIcSZ2WQcfMzddLi61OmPB3zdKRABt57hj1wbIoQxHUsbsmtHRLZ3fT1V37RLQXfu3GzgjuPLYWxVdQRM7T4v5rhecY7c53ilFIr6KIfeIZ0DY5SGXLWqLoYfN7ZrHHEAONrId0GMeRO2Y0j4uF8j4RXJUpk81wUlFgnlGFkCSKwnXLK7aqYMPri4w0Bp0GixZ7E1JHWOlWDM40VXw5jBz7KnkClba6IaDJNgT8UeUDRHNhNVDiXIWSHLJAUzQqGN5RmG7X6ttpRgQPFpBPXX3UsA758WWSB7d4cNAniSp2jHMhSIl2kRkEnXkm8yuk0B08tDIIEZvDj6zvSsLqDuCmUwpUPcYdsofagnP8WIFoH1fKe4AbbzgUXzTCPgMjKkRvBKoXUgnpWtuNCoz2cosaxDDSOUEuBgX58UltaybzjqS1jMs3F3X3Ewjm2M0wWTeLjuXc3WLjF7OBQAvdDxLUQDRIGDFeeadqbe1gdC7ONr3gZY7w3mYwTJVlCaA0P4qRxhDUDItZNgLEpx4unTsO5Te51PD3YeicmqHlJbxknhjYpciOhfWYrmYGvCCl0xyga0hZ74EDiL1iLQjr1ADRa40SmUh1ufvfbZzcr5OpkttKmeeA75LjDIi58WvajJk0o1bKTgos7OTmhs5LT3cMZ3XJV4An4xtoCNGK4Ktreh6rXTnmHRCQ3HP2kfOTykNT2T8b6vS8rtnsqaLy862mTDBYKnqichIMvyN8fhEaQX0eP5iAs7jn2SrEybNAVOpYzaz6bRFVk1POPaHlkRysYOxGs2r8qumcpSs8ylD3YN2nPCc6OVpBCRw2YT1wozwOOA03r8hDNNz3ZhrNPY6EoW28mOApChU2QHcV63L4S5RiKJYOpAAOeApF5xGOuYnT8Lc4YUHVuwpNSZmxclNL6dzA3MJtCl88J3sZWcuigBgWiDjLUgeVnObW55nj7bYWkZB6UqmBCNNaWaIVkchCMtHNnvHnnoonLuBQTpnHdWy0kXUwY2o3Bd5jnDOQgEMVkiWgoOhRVMbt0cRvxQwSMYkkMyarg1OuYxAGhtY7Orsu1YEhs3MITDhzm4NDDEusaIXdDSaNl4u2ScTYKIsYchLBYo7fa2pvx4oUuaOHAi2oNPRR05zP5pqycSsDpnkEz6YIYBQiZaRgVRp407t83',48913,'7JKWzvKJ4KMb2gz3geo18sMbpkVZNTrYPCvIGjPeO4X5l6KkgYEdfNnGOJFgoeiRbMnLhZ8ahfiNr1VFFRMMIZsp12FAgU0kYTsVRU0ElqlMSs4PCYYqQw2wvqNMnkir8Bm0zYynnDEFIV6h1Dwg42aIFi7ZykkRXj6vQBDTFnYKFjhmrzsnXMLwXjF6Mhf0FMwiuZmbYPacX6KncUeHlUj3oWp6vOxtx5egjBQX1nMH5MZuDG4DYNUFPAPqYxIOWWLiTXDn8qCGcDjwKUWtyBfBkAVjknjxWGtP8ReaRY5yjLKdjWEdhZut1lbGChE8ZbzHSoDqQeyOskrl2ayI6u6ilUZ8kuPLPB60NeE2gOLUGtLUw2L3CPOC7wwMd1SloFV0BLP5LypjWGXHejeR1tK3DRoFyfewWqMCk5wloIn2bgSiam5LiFgRWOZJDQ0METm8JS0geMjkYZlNO3SY8A7U73lrFIAfeoyjy1dtQCxg6BnlhLU5SQZpitqFozzg0QKFpupdKs7zeC3HpbnUZNQIhI0gspIUOzvUgBNyDCh6aHnDrXfrVK38rMPvrdvcFdQFlVvzbjrv4h7mJjfGBarBGvGRplvRT4Iw663YYxeDq5f2DK5NETBEOTnC8wFzmBArRTDn6UPDl2fRvvalugyQGPNxjPBBPAXQXXKZrE1iC7Sah84hJyBkg2ZeX6qTrYRdxxvWISNDPJIUPCUuN66K6GLAEC1TVfQLb5VQUEaU8vHXExASC7TQ1uyOEmAYDNPHLAfZUQvrm3aI8C43nWmjEc4l85NBx2pyBW3RW2Dfm8LfrFGmh4LuIRowmyX','RGkX1uNIo63J8YGY6a2TiQ4bPxZkcogKw06lEueIRoVt7lcroyQ66OCPF3xf2pVlRXuBqsWTpHmIJkxzixQrAdCaSwRrPOTSfGrzRGT0z1uhFffChtF4vboImAHJqDUMyiERy0GRiBrmqbgBxZohVdpY3cjhQiDrb7zSsuUSFkhWGIpKGrxWFZsj2LW50zufBj4FmXL262I3awzG474YMoGva6si5eMgSn5sIdwceqAEMAGJlZquOYuVQwzkuAcBn7zQANsvNZ25HSLCQ04Ypqi3bHTymNGDl0vjXqiVg8Zlx4AZnymHpCbWDWfzJynd0gKdWsVViblFg15zKRYsxqFPCSX2mgV7tRzvjVh7lvUgRc8oclPgG1LNxhl0CGDhmzQIrjAkUihQ0LSKCpxJzAIuBoCEKhjhBGKdByeiYAyV24aQ1MXtDnyLD38wBQGrSZtvXK0g5YT6VvHS8EhTfUmnd0OwvoxHDwXCzGnCnxXZW7Hm3bRXNdJf1p5uQVv7ajmXiQukTx8yRdz42gQhWLiG5FmeJbWK4R4zqORHXTougezuF2RthvqDG7yLAvMPu4Ou8PikFF7qK67BlIh3DWKcgO2fgZbuzp2cxrJNSjyaF5aBTPCyshLYNSAJEqTZH7N8WO5nwL4yWUxKlKxSJiOpOwCYVdoNJWSP8HHTgtLQjXYrd2DuomNJTU0iW13Pv3VzBwB8IoO84pzjaxPBZTgqFAuone5up7jw6dzssIbJ7C4FGUIG2ZUj8RPzhl7m6YjaG1jKvH2SDfubYfissUPuWasIvLlnuGx3mHBFgFH60OdAtWlPWllY3QF1V5B0QBx5Mkim3viyzQogiEcGHWJ3dNIEhe6WaSRKNvY1mUETz6md2M23uQNeuDhFfFCXeezgQFchBIZN5Zuhtb1muJ2yv47M053ffhHd4ByawSMM570wVpP5xLuDHICH8OYflLC4XSjS8KEECz4tGIS1SwCSHyU2fJb6bsivDVE8PPaXA6uNLi2h6rxb644cXr1P6DOinuvuSJl3kAVSRCHLPvdGysRtDN3iwzhQpzXi1xrjnE5F1GOD6R7AOZPfEZ7EwVLsshWSyUWzfjiexsE2H6gHMlnyGesQBBC27JbO4txGKlWCJqDiAcLMxh5ikTdKLQALdRIlrYnrIkSXkrSIChgvnVr3uvh1PqDTCWqOrsoQiY3X0PxrQjA5c2mpSWamAuZFVQ3YWs2BUBsWFqqowqXGRkTLqrxHEAwgUxTFXvBvUW2nlys6stX88WFFp7Z4vO8wYwy2mc1WDkew8MCzBoHXrDwwGP5l1mncQmeOMU5TwFfJhT6G40JjB1PaNKe0rBmgdmMxveDiSnADiDleV3ric5pYDKCTnGEx56wlzMnt7446uqGs16uvJnbAVTWe2ix368d66PPgWyUJiKgE0ZhmMOKiKW2f5Hp3XRypTLlFqxxLPtI0P77yLYW6TROAmwx3ymWouRTWvIV1lGEwon0AhiKy6wRJDiGy0VoP3M766s8VAbogVXYUh7WFAej1chgxsSuU7OxF1dOtfzuneNH0UWE1F6ynN2Wum3xbzoer5rKsv2suOba80LxdeCHEKNyOyK5860x6JZhEJZIUfgMF4HTav7mtaifW4yyIVXcdxXOslBJUisGenwgE7PsdXehd0iqGKH8BBuOECjWPIuGG2aS51uRHUs31r2wxPpq4XxNcoP5B8V6T7cPINPbf7bjoMYI5aI8MRRQZBEH8aoZMaY0mhOYWeLKcCyrhf6v8eitWX4QY6wjQ5QwCloo0iS7ESCuQEjc5slwscscmRx3bKPTwV1e0tGyizKceUiwmxFiImC4me7ts1hYKk2AKdCWPwtEew3khFhV8dE2Bo1jLZRuTeCCSjuZKuejLTV0E7Xw3TxmAT7tlDrsd8JuDRuqriBF1TLkd0knIWG4cehoOZIEVVjLKTEABMAYOWm6JORttKrsx0FfAlzRcBJlLQofVhD3xVltnrIVYbczWkai0QQSiySib2c1WYa5t2FG0qaMNwGZf1BZagXrRQgexMS428EBrtmSCZYoNAcfVzSrCC6M5jkRyBHw','VZ7DnA7vcofPtMwPPulenNpC7ErJPaLsWy2XipWF02D1ZwzXCwC8hJ6MrII3PKYGLklG0SzrMqU0','BfjqAIQ6gwX3Xhjl338BqTJaMZUKxzMcdTovIPF6iD3lXeW4szUglzWNmFKXlYQ71cRQM1v0BAZwUqf1lRZfCsKnPlJIDdgy0JmHrfVHGGy84c3NMf7TRuNOeqj7xUYCV','Aox4fssjHKLaZwTS0Bq',57753,NULL,'C:\DOCS\TEMP75');
exit when c%notfound;
end loop;
close c;
commit;
end;

trying to read cursor from record but getting exact fetch returns more than requested number of rows?

I am trying to read cursor from record but getting that error
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 14
declare
ename table1.ename%TYPE;
seq_ENAME NUMBER (4);
CURSOR List_ENAME_cur IS
SELECT ENAME from table1
WHERE status = 2 AND ROWNUM <= 100;
begin
FOR List_ENAME_rec IN List_ENAME_cur
loop
select substr(ename,5,4),ENAME into seq_ENAME,ename from table1 where REGEXP_LIKE(ENAME,'[1-9]{4}[_][1-9]{2}[_][1-9]{2}[_][1-9]{2}[_][0-9]{4}');
DBMS_OUTPUT.PUT_LINE('seq_ENAME'||seq_ENAME);
end loop;
end;
At the moment your cursor and the select you are doing inside the loop are not related. The cursor loop is just identifying up to 100 records and you're looping over those, but not using the results. You're almost doing:
for i in 1..100 loop
select ... into ... from ...
end loop;
So each time around the loop you're trying to select all rows into your variable, hence the error you're getting.
You can refer to the cursor variable inside the loop, as list_ename_rec.ename. But you're adding a where clause inside the loop; you can still do that test inside the loop, but you might as well do it in the cursor declaration:
declare
CURSOR List_ENAME_cur IS
SELECT ENAME, substr(ename,5,4)
from table1
WHERE status = 2
AND REGEXP_LIKE(ENAME,
'[1-9]{4}[_][1-9]{2}[_][1-9]{2}[_][1-9]{2}[_][0-9]{4}')
AND ROWNUM <= 100;
begin
FOR List_ENAME_rec IN List_ENAME_cur
loop
DBMS_OUTPUT.PUT_LINE('seq_ENAME'||List_ENAME_rec.seq_ENAME);
end loop;
end;
Alternatively, if you want to get 100 records but then only display the ones within that set which match your pattern you could do this:
declare
seq_ENAME NUMBER (4);
CURSOR List_ENAME_cur IS
SELECT ENAME from table1
WHERE status = 2
AND ROWNUM <= 100;
begin
FOR List_ENAME_rec IN List_ENAME_cur
loop
if REGEXP_LIKE(List_ENAME_rec.ENAME,
'[1-9]{4}[_][1-9]{2}[_][1-9]{2}[_][1-9]{2}[_][0-9]{4}')
then
seq_ENAME := substr(List_ENAME_rec.ename,5,4);
DBMS_OUTPUT.PUT_LINE('seq_ENAME'||seq_ENAME);
end if;
end loop;
end;
Either way, it's worth noting that which 100 rows you get from the table is indeterminate, because you don't have an order by clause.

Resources