13 Cursors Exception
13 Cursors Exception
13 Cursors Exception
■objectives :
–explain what is a cursor
–list the types of cursors
–list & explain implicit cursor & its attributes
–state & explain syntax for declaring, opening and fetching data
from explicit cursors
–list & explain explicit cursor attributes
–explain a cursor for loop
–construct a pl/sql programs using cursors
■what is a cursor ?
–a cursor is a pl/sql construct that lets you individually
manipulate each row in a set of rows returned by a
query
cursors
■there are two types of cursors
–implicit cursors
■an implicit cursor is created implicitly by pl/sql
–explicit cursors
■an explicit cursor is a user defined cursor
implicit cursor
■created by oracle automatically with default name
sql
■you cannot process data by using an implicit cursor
■you can use certain attributes to access information
about the most recently executed statement
■attributes are prefixed by keyword sql
■implicit cursor attributes are :
–sql%notfound
–sql%found
–sql%rowcount
–sql%isopen
implicit cursor
attribute description
sql%notfound result of the dml statement (boolean )
- true if not successful
- false if successful
explicit cursor
■an explicit cursor is a user defined cursor
■pl/sql allows you to process the rows returned by a
query by using an explicit cursor
■you can process data in an explicit cursor
■defined in the declaration section of the pl/sql block
■manipulation is done through open, fetch and close
statements
■processing information can be accessed using its
attributes
■steps in using explicit cursor are :
–declaring a cursor
–opening a cursor
–fetching rows from an opened cursor
–closing a cursor
declaring a cursor
■a cursor is defined in the declaration section of the
pl/sql block
■declaring a cursor is defining its active set of rows
■this active set of rows can be used to view or modify
data
■syntax :
■example 1:
declare
cursor emp_cursor (p_job char ) is
select ename, sal, job from emp
where job =p_job ;
begin
:
end;
opening a cursor
■acursor is to be opened before you can use it to
read or modify data
■when you open a cursor
–itsassociated query is evaluated
–the active set of rows become available
■syntax :
open <cursor_name> [(argument list)];
■a cursor cannot be opened if
–cursor has not been declared yet
–it is already open
fetching data from a cursor
■when you open a cursor, the cursor points before the first
row in the active set
■each fetch operation retrieves a row from the active set
■first fetch command moves pointer to the first row and then
retrieves that row
■successive fetch commands fetch successive rows
■syntax :
fetch <cursor_name> into
variable_name1, variable_name2 ……..;
■variables after into clause in the fetch command
and column list in the select statement should
have matching data types
■example :
declare
v_empno emp.empno%type;
v_ename emp.ename%type;
v_sal emp.sal%type;
cursor emp_cursor is
select empno, ename, sal from emp;
begin
open emp_cursor;
-- fetches first row
fetch emp_cursor into v_empno, v_ename, v_sal;
-- fetches second row
fetch emp_cursor into v_empno, v_ename, v_sal;
:
close emp_cursor;
end;
closing a cursor :
■you can use close statement to close the cursor
■the close statement
–disables the cursor
–relieves resources
■syntax :
close <cursor_name>;
■you can reopen the cursor again, if required
■if you perform any operation on a closed cursor, the
pre-defined exception invalid_cursor is raised
■example 1:
loop
fetch emp_cursor into v_empno, v_ename, v_sal;
exit when emp_cursor%notfound;
……………..
end loop;
■example 2:
loop
fetch emp_cursor into v_empno, v_ename, v_sal;
if emp_cursor%found then
-- do some processing
else
exit;
end if;
end loop;
■example 3:
:
fetch emp_cursor into v_empno, v_ename, v_sal;
if emp_cursor%rowcount > 10 then
-- do some processing
end if;
:
■example 4:
if emp_cursor%isopen then
-- cursor is open
-- do some processing
else
open emp_cursor;
-- open cursor if not already open
end if;
■example 5:
open emp_cursor;
loop
fetch emp_cursor into v_empno, v_ename, v_sal;
exit when emp_cursor%notfound;
end loop;
v_counter := emp_cursor%rowcount;
if emp_cursor%rowcount > 50 then
v_rowsover50 := true;
end if;
declare
v_empno emp.empno%type;
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
for cur_rec in (select empno,ename,sal from emp where deptno = 10)
loop
dbms_output.put_line(cur_rec.empno||' having name as'||cur_rec.ename|| ' has sal of rs: '||
cur_rec.sal);
end loop;
end;
parameterized cursors
declare
vename emp.ename%type;
vsal emp.sal%type;
cursor cur_emp(p_deptno number) is select ename,sal from emp where deptno = p_deptno;
begin
open cur_emp(&deptno);
fetch cur_emp into vename,vsal;
loop
exit when cur_emp%notfound;
dbms_output.put_line('employee is '||vename||' has sal '||vsal);
fetch cur_emp into vename,vsal;
end loop;
close cur_emp;
end;
exception handling
■objectives :
–identify the need of exception handling
–list types of exceptions
–list the pre-defined exceptions
–state & explain how to declare a user-defined exception
–state & explain how to raise exception
–state & explain how to write an exception handler
–list error reporting functions
–construct pl/sql programs with exception handling
predefined exceptions
■predefined exceptions are error conditions that are
defined by oracle
■predefined exceptions can not be altered
■predefined exceptions are raised automatically
whenever a pl/sql program violates an oracle rule
■if an action is to be taken for an exception, when
raised, you require a handler for it
■exception handler is written in the exception
handling section of a pl/sql block
user-defined exceptions
■a user-defined exception can be defined in the
declarative section of pl/sql block
■syntax :
<exception_name> exception;
■example :
declare
:
insufficient_balance exception;
:
begin
:
exception
:
end;
raising exceptions
■once you have declared an exception, you can raise the
exception in the program
■the keyword raise is used to raise an exception
■syntax :
raise <exception_name>;
■predefined exception can also be raised using raise
keyword
■example :
declare
insufficient_balance exception;
begin
:
if credit_limit < sales_amount then
raise insufficient_balance;
end if;
:
end;
execution of exceptions
■once an exception is raised
–the control is transferred to the exception handling
section of a pl/sql block
–an associates exception handler, if found, is executed
–if an associated exception handler is not found then
control propagates to the outer block
–if exception handler is not found pl/sql reports error
■example 1:
declare
insufficient_balance exception;
begin
:
if credit_limit < sales_amount then
raise insufficient_balance;
end if;
:
exception
when insufficient_balance then
insert into temp (char_store)
values (`balance is insufficient’);
end;
declare
v_cust_id customer.custid%type;
v_credit_limit customer.creditlimit%type;
-- user-defined exception
insufficient_balance exception;
begin
select custid, creditlimit into v_cust_id, v_credit_limit from customer where
custname = `seed’;
if v_credit_limit < v_sales_amount then
raise insufficient_balance;
end if;
:
exception
when no_data_found then -- predefined exception
insert into temp(char_store)
values (`customer not present’);
when insufficient_balance then -- user-defined exception
insert into temp(char_store)
values (`balance is insufficient’);
end;
■example 3:
declare
-- user-defined exception
out_of_stock exception;
v_qty_on_hand number(5);
begin
…
if v_qty_on_hand < 1 then
raise out_of_stock;
end if;
exception
when out_of_stock then
insert into temp (char_store)
values (`item out of stock’);
…
end;
exception
when no_data_found then
…
when my_exception then
…
end;
sqlcode function
■sqlcode function returns the error number
associated with most recently raised exception
■sqlcode function is used within an exception handler
■if you use outside it returns value zero
sqlerrm function
■sqlerrm function returns the error message associated with
an error number
■sqlerrm function is used within an exception handler
example 1
■create a pl/sql block which accepts a customer number
from the user and checks whether there are rows matching
the customer number in sales table
■accordingly pl / sql inserts a row in an operations table
based on the following conditions
–if no rows are found insert a row in operations with a
remark “no rows found”
–if more than one rows are found insert a row in operations
with a remark “multiple rows found”
–if one row is found insert a row in operations with a
remark “one row found”
–for other columns, insert appropriate values. user pseudo
column can be used for username column
declare
p_custid sales.custid%type;
begin
p_custid := &customer_number
select custid into p_custid
from sales
where custid = p_custid;
insert into operations
values( p_custid , ‘one order for the customer ’);
exception
when no_data_found then
insert into operations
values ( p_custid , ‘no order for the customer ’);
when too_many_rows then
insert into operations
values (p_custid , ‘multiple orders for the customer ’);
end;