Thanks for the question, Geoff.
Asked: March 03, 2011 - 9:02 pm UTC
Last updated: March 04, 2011 - 7:45 am UTC
Version: 10.2.0, 11.2.0
Viewed 10K+ times! This question is
You Asked
Hello Tom,
I'm using FORALL in a procedure. I find that in after an invocation which affects no rows the sql%rowcount is not initialised to 0 but has the value from the previous invocation.
I expected:
1) that the data structures associated with forall would be initialised each time I called the procedure and would have no memory of previous values
2) as the last execution of the statement affected no rows the sql%rowcount would be 0.
Test code follows. It happens in 10.2.0 and 11.2.0.
Regards,
Geoff
------------------------------------------------------------------------------
TEST CODE
------------------------------------------------------------------------------
create table t (dtype varchar2(10), dval integer);
create or replace package test_pkg as
procedure insert_t;
end test_pkg;
/
create or replace package body test_pkg as
type inttab_type is table of pls_integer index by pls_integer;
procedure insert_t is
tab1 inttab_type;
tab2 inttab_type;
tab3 inttab_type;
procedure do_insert (tabname in varchar2, tab in inttab_type) is
begin
dbms_output.put_line(tabname||'.count= '||tab.count);
forall i in 1..tab.count
insert into t (dtype, dval) values ('TAB1',tab(i));
dbms_output.put_line('Inserted '||sql%rowcount||' '||tabname||' records');
end;
begin
for i in 1..6 loop
tab1(i):= i;
end loop;
for i in 1..3 loop
tab3(i):= i;
end loop;
do_insert('TAB1',tab1);
do_insert('TAB2',tab2);
do_insert('TAB3',tab3);
end insert_t;
end test_pkg;
/
show errors package body test_pkg
set serveroutput on size unlimited format wrapped
exec test_pkg.insert_t
drop package test_pkg;
drop table t;
-----------------------------------------------------------------------------
OUTPUT
-----------------------------------------------------------------------------
SQL> exec test_pkg.insert_t
TAB1.count= 6
Inserted 6 TAB1 records
TAB2.count= 0
Inserted 6 TAB2 records
TAB3.count= 3
Inserted 3 TAB3 records
PL/SQL procedure successfully completed.
and Tom said...
If you execute forall i in 1..0 <statement> - how many times is the body of the forall executed? It is executed 0 times - and the sql% attributes are set as a side effect of executing a statement. (the forall isn't the trigger, the statement is). If the statement never executes - then.... what is the value of the sql% stuff??
You never entered/executed the forall, hence you never fired a statement, hence the sql% attributes are left as they are - you never did any sql (and doing sql is what affects the sql% stuff)
Is this answer out of date? If it is, please let us know via a Comment