cursors

sobjectives : –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 swhat –a

is a cursor ?

cursor is a pl/sql construct that lets you individually manipulate each row in a set of rows returned by a query cursor allows row by row processing of a data in a table

–a

cursor management in pl/sql
swhen

sql commands are executed, oracle uses work areas sthis storage area is called the implicit cursor spl/sql allows users to name the private work areas and access the stored information scursor attributes are predefined variables that are helpful in finding out the details about the cursor

cursors
sthere

are two types of cursors

–implicit cursors san implicit cursor is created implicitly by pl/sql –explicit cursors san explicit cursor is a user defined cursor

implicit cursor
screated

sql syou cannot process data by using an implicit cursor syou can use certain attributes to access information about the most recently executed statement sattributes are prefixed by keyword sql simplicit cursor attributes are :
–sql%notfound –sql%found –sql%rowcount –sql%isopen

by oracle automatically with default name

implicit cursor
sql%notfound result of the dml statement (boolean ) - true if not successful - false if successful sql%found result of the dml statement (boolean ) - true is successful (i.e. dml returned at least one row) - false if not successful contains number of rows affected by last sql statement false always because oracle ( boolean ) automatically closes implicit cursor after executing its sql statement

attribute

description

sql%rowcount ( number ) sql%isopen

scursor –open –fetch

methods

and –close methods cannot be used with implicit cursor sql

implicit cursor

sexample declare v_rowsaffected number (6); begin update emp set comm = 500 where job = ‘salesman’; v_rowsaffected := sql%rowcount; insert into updated_records values (‘emp’, v_rowsaffected, ‘salesman’, sysdate); end;

explicit cursor
san

explicit cursor is a user defined cursor spl/sql allows you to process the rows returned by a query by using an explicit cursor syou can process data in an explicit cursor sdefined in the declaration section of the pl/sql block smanipulation is done through open, fetch and close statements sprocessing information can be accessed using its attributes ssteps in using explicit cursor are :
–declaring

a cursor –opening a cursor –fetching rows from an opened cursor –closing a cursor

declaring a cursor
sa

cursor is defined in the declaration section of the pl/sql block sdeclaring a cursor is defining its active set of rows sthis active set of rows can be used to view or modify data

ssyntax

:

s

cursor <cursor_name> [(<parameter_list>)] is <select ………………statement >; example 1 :
declare cursor emp_cursor is select ename, job, sal from emp; begin : end;

declaring a parameterised cursor
san

explicit cursor can take parameters susing parameter you can decide active set at runtime
sexample

1:

declare cursor emp_cursor (p_job char ) is select ename, sal, job from emp where job =p_job ; begin : end;

opening a cursor
sa

cursor is to be opened before you can use it to read or modify data swhen you open a cursor
–its ssyntax

: open <cursor_name> [(argument list)]; sa cursor cannot be opened if
–cursor

associated query is evaluated –the active set of rows become available

has not been declared yet –it is already open

fetching data from a cursor
swhen

you open a cursor, the cursor points before the first row in the active set seach fetch operation retrieves a row from the active set sfirst fetch command moves pointer to the first row and then retrieves that row ssuccessive fetch commands fetch successive rows
ssyntax

: fetch <cursor_name> into variable_name1, variable_name2 ……..; svariables after into clause in the fetch command and column list in the select statement should have matching data types
sexample : 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;

cursor processing using a loop:
syou sexample

can fetch rows and process them without use of multiple statements :
open emp_cursor; loop fetch emp_cursor into v_empno, v_ename, v_sal; exit when emp_cursor%notfound;

-- process row here end loop;

closing a cursor :
syou –disables ssyntax

can use close statement to close the cursor sthe close statement : close <cursor_name>; syou can reopen the cursor again, if required sif you perform any operation on a closed cursor, the pre-defined exception invalid_cursor is raised
the cursor –relieves resources

explicit cursor attributes
seach

cursor has four attributes sattributes are appended to the cursor name
attribute description %notfound evaluates to true, if the fetch no more rows are left %found evaluates to true, if the last fetch succeeded attribute description %rowcount returns the number of rows till now %isopen evaluates to true, if the cursor is open failed i.e.

fetched

sexample

1:

loop fetch emp_cursor into v_empno, v_ename, v_sal;

exit when emp_cursor%notfound; …………….. end loop;
sexample

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;
sexample

3:

: fetch emp_cursor into v_empno, v_ename, v_sal; if emp_cursor%rowcount > 10 then -- do some processing end if; :
sexample

4:

if emp_cursor%isopen then -- cursor is open -- do some processing else open emp_cursor; -- open cursor if not already open end if;
sexample

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;

cursor for loops
slooping

constructs require explicit cursor processing sa cursor for…loop can simplify the code

sa

cursor for…loop implicitly
–declares

ssyntax

: for <row_var> in <cursor_name> loop <statements> end loop;

a record structure which stores fetched value –opens cursor implicitly –fetches one row at a time –closes the cursor

declare v_qohand itemmast.qoh%type; /* select those records which are not updated */ cursor update_items is select itno, trantype, qty from itemtran where upper (updt) = ‘n’; begin for item in update_items loop select qoh into v_qohand from itemmast where itno = item.itno; if upper(item.trantype) = ‘r’ then v_qohand := v_qohand + item.qty; else v_qohand := v_qohand - item.qty; end if; update where update where end loop; commit; end; itemmast set qoh = v_qohand itno = item.itno; itemtran set updt = ‘y’ itno = item.itno;

declaring a cursor in cursor for loop
syou

can declare a cursor in a cursor for loop itself scursor name in the for statement is replaced with the select statement query

sexample

declare v_result number; begin for each_record in (select num1, num2, num3 from numtable) loop v_result := (each_record.num1*45 / each_record.num2) + each_record.num3; insert into output_table values (v_result); end loop; end; 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
sobjectives : –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

exception handling in pl/sql
sin

pl/sql, a warning or an error condition is called an exception swhen an error occurs
–an

sexception –internal

can either be internally defined by runtime systems or can be user-defined
exceptions are raised automatically –user-defined exceptions must be raised explicitly –you can also raise internal exceptions explicitly

exception is raised –normal execution stops and the control transfers to the exception handling section

predefined exceptions
spredefined

exceptions are error conditions that are defined by oracle spredefined exceptions can not be altered spredefined exceptions are raised automatically whenever a pl/sql program violates an oracle rule sif an action is to be taken for an exception, when raised, you require a handler for it sexception handler is written in the exception handling section of a pl/sql block
ssome

of the predefined exceptions are
description raised when you try to open an already open cursor

exception name cursor_already_open

dup_val_on_index invalid_cursor invalid_number

raised when you try to insert some duplicate values in a table column with unique or primary key constraint raised when you do an illegal cursor operation raised when there is a failure of conversion of char type string to a number in a sql statement raised when you try to log on to oracle with an invalid username or password raised when select ...into statement returns no rows raised when select ... into statement returns more than one row raised when pl/sql runs out of memory or memory is corrupted raised when you execute a pl/sql program referring to a database without actually logging on to the database

login_denied

no_data_found too_many_rows program_error not_loged_on

user-defined exceptions
sa

user-defined exception can be defined in the declarative section of pl/sql block :

ssyntax

<exception_name> exception; sexample :
declare : insufficient_balance exception; : begin : exception : end;

raising exceptions
sonce

you have declared an exception, you can raise the exception in the program sthe keyword raise is used to raise an exception
ssyntax

: raise <exception_name>; exception can also be raised using raise

spredefined

keyword
sexample

:

declare insufficient_balance exception; begin : if credit_limit < sales_amount then raise insufficient_balance; end if; : end;

execution of exceptions
sonce –the

an exception is raised

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
sexample
declare begin insufficient_balance exception; : 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;

1:

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;

sexample

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;

example : scope rule for exceptions declare my_exception exception; begin --some code goes here declare -- start of a new sub block insufficient_balance exception; my_exception exception; begin … if … then raise my_exception; end if; … if … then raise insufficient_balance;

exception end;

end if; … if … then raise no_data_found; ... end if; …
when insufficient_balance then … -- end of a new sub block

exception when no_data_found then … when my_exception then … end;

handling unnamed exceptions
syou

may handle the unnamed exception by using an others exception handler sthe others handler catches all the exceptions that the block does not name explicitly sthe others exception handler must be defined after all the exception handlers
sexample

:

begin …

exception when no_data_found then -- some code here when others then rollback; end;

error reporting functions
swhen

an error condition is encountered, you might need to know its error number and the message serror reporting functions can be used to get this information sthese functions are
–sqlcode –sqlerrm

sqlcode function
ssqlcode

function returns the error number associated with most recently raised exception ssqlcode function is used within an exception handler sif you use outside it returns value zero

sqlerrm function
ssqlerrm

function returns the error message associated with an error number ssqlerrm function is used within an exception handler
sif

you use outside it returns the message : ora-0000: normal, successful completion
declare error_msg error_num begin …

sexample

:

varchar (50); number;

exception … when others then error_num := sqlcode; error_msg := sqlerrm (error_num); insert into errors values (error_msg); end;

example 1
screate

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 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

saccordingly

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;

Sign up to vote on this title
UsefulNot useful