| René Nyffenegger's collection of things on the web | |
|
René Nyffenegger on Oracle - Most wanted - Feedback
|
Cursor attributes | ||
|
There are five cursor attributes: %isopen, %found, %notfound, %rowcount and %bulk_rowcount. In order to demonstrate these, the following table
is created...
create table cur_attr_exmpl ( a number, b varchar2(20) );
... and filled with these values:
insert into cur_attr_exmpl values ( 1, 'one' ); insert into cur_attr_exmpl values ( 2, 'two' ); insert into cur_attr_exmpl values ( 10, 'ten' ); insert into cur_attr_exmpl values ( 20, 'twenty' ); insert into cur_attr_exmpl values ( 42, 'fourty-two' ); insert into cur_attr_exmpl values ( 101, 'one hundred and one'); insert into cur_attr_exmpl values (1000, 'thousand' ); %isopen
With %isopen it is possible to test whether a cursor was opened:
declare
cursor cur is
select b
from cur_attr_exmpl;
b_ cur_attr_exmpl.b%type;
procedure is_cursor_open(txt in varchar2) as begin
dbms_output.put(txt);
if cur%isopen then
dbms_output.put_line('cursor is open');
else
dbms_output.put_line('cursor is not open');
end if;
end is_cursor_open;
begin
is_cursor_open('First test: ');
open cur;
is_cursor_open('Second test: ');
fetch cur into b_;
is_cursor_open('Third test: ');
close cur;
is_cursor_open('Fourth test: ');
end;
/
First test: cursor is not open Second test: cursor is open Third test: cursor is open Fourth test: cursor is not open %found
%found returns true when the last fetch operation on the cursor fetched a row. If %found is used on a cursor that is not open
(%open returns false), an ORA-01001: invalid cursor is raised. %notfound returns null is
returned:
declare
cursor cur is
select b
from cur_attr_exmpl
where a between 40 and 140;
b_ cur_attr_exmpl.b%type;
begin
begin
if cur%found then
dbms_output.put_line('Cursor found');
end if;
exception
when invalid_cursor then
dbms_output.put_line('%found only possible if cursor is open');
when others then
raise;
end;
open cur;
if cur%found then
dbms_output.put_line('Cursor opened and %found true');
elsif cur%found is null then
dbms_output.put_line('Cursor opened and %found null');
else
dbms_output.put_line('Cursor opened and %found false');
end if;
loop
fetch cur into b_;
if cur%found then
dbms_output.put_line('fetched: ' || b_);
else
exit;
end if;
end loop;
close cur;
end;
/
%found only possible if cursor is open Cursor opened and %found null fetched: fourty-two fetched: one hundred and one %notfound
%notfound returns true when the last fetch operation on the cursor did not fetch a row. If %notfound is used on a cursor that is not open
(%open returns false), an ORA-01001: invalid cursor is raised. %notfound returns null is
returned:
declare
cursor cur is
select b
from cur_attr_exmpl
where a between 40 and 140;
b_ cur_attr_exmpl.b%type;
begin
begin
if cur%notfound then
dbms_output.put_line('Cursor notfound');
end if;
exception when others then
if sqlcode = -1001 then -- ORA-01001: invalid cursor
dbms_output.put_line('%notfound only possible if cursor is open');
else
raise;
end if;
end;
open cur;
if cur%notfound then
dbms_output.put_line('Cursor opened and %notfound true');
elsif cur%notfound is null then
dbms_output.put_line('Cursor opened and %notfound null');
else
dbms_output.put_line('Cursor opened and %notfound false');
end if;
loop
fetch cur into b_;
if cur%notfound then
exit;
else
dbms_output.put_line('fetched: ' || b_);
end if;
end loop;
close cur;
end;
/
%notfound only possible if cursor is open Cursor opened and %notfound null fetched: fourty-two fetched: one hundred and one %rowcount
%rowcount returns the number of rows that have been fetched so far. So, it increases with each fetch:
declare
cursor cur is
select b
from cur_attr_exmpl
where a between 9 and 90;
b_ cur_attr_exmpl.b%type;
begin
open cur;
loop
fetch cur into b_;
if cur%found then
dbms_output.put_line(cur%rowcount || ': fetched: ' || b_);
else
exit;
end if;
end loop;
dbms_output.put_line('Totally ' || cur%rowcount || ' rows fetched');
close cur;
end;
/
1: fetched: ten 2: fetched: twenty 3: fetched: fourty-two Totally 3 rows fetched %bulk_rowcount
%bulk_rowcount is similar to %rowcount, but is used in bulk collects.
declare
cursor cur is
select b
from cur_attr_exmpl
where a between 9 and 90;
type b_t is table of cur_attr_exmpl.b%type;
b_ b_t;
begin
open cur;
fetch cur bulk collect into b_;
for i in 1 .. b_.count loop
dbms_output.put_line(' ' || b_(i));
end loop;
dbms_output.put_line('');
dbms_output.put_line('Totally ' || cur%rowcount || ' rows fetched');
close cur;
end;
/
ten twenty fourty-two Totally 3 rows fetched |