Skip to Main Content
  • Questions
  • On FORALL affecting no rows, sql%rowcount is not initialised

Breadcrumb

Question and Answer

Tom Kyte

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

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library