You are on page 1of 55

Cursor and

Exception Handling
By Nidhi Bhatnagar
Objectives
Cursor with For Loops
Cursor with Parameters
For Update of - Where Current of Cursor
Ref Cursor
Exception Handling Understanding
Exception Handling various types
Cursor with For Loops
It makes the code bit easier to maintain and use
if we make use of FOR Loops in Cursors.

Reason , it reduces the number of steps needed
while working with cursor.

Cursor in case of FOR Loops do not require
Open, Fetch or Close cursor steps.
Cursor with For Loops
It becomes a two step process
Step1 : Declare a cursor
Step2 : Declare a Record Type or Row Type
variable and just use it in For Loop with
Cursor

Cursor with For Loops
Example
Declare
Cursor c_emp IS
Select * From Emp;

v_emp c_emp%Rowtype;

Begin
For v_emp in c_emp
Loop
dbms_output.put_line(v_emp.empno || || v_emp.sal);
End Loop;

End;

Cursor with For Loops
For Loop automatically:
Open a cursor
Fetch from first to last record in a cursor
Query.
Close the cursor.

It is thus simple to work with For Loops in
case of cursors.
Cursor with For Loops
However there is slight change in For Loop
when we work with cursor.

Normally it is : For i in 1..10

In case of cursor it is: For variable IN cursor

For Variable IN Cursor
Loop
<Code>
End Loop;
Example
FOR record_index in cursor_name
LOOP
{.statements.}
END LOOP;


Cursor with Parameters
PL/SQL also allows you to pass parameters into cursors.

The rationale for using parameters in cursors is that it
makes the cursor more reusable.

Instead of hardcoding a value into the WHERE clause
of a query to select particular information, you can use a
parameter and then pass different values to the WHERE
clause each time a cursor is opened.
Cursor with Parameters
In case of cursor with parameters step1 and step2
Declare Cursor
Open Cursor
changes:

Step3 and Step4
Fetch cursor
Close cursor
remains the same
Cursor with Parameters
Changes in Declare
Cursor Cur_name(parameter1 <Datatype>, parameter2
<Datatype) IS

Select * from tablename where condition1 = parameter1 and
condition2 = parameter2 ;

Example:
Cursor c_emp (p_deptno emp.deptno%type) IS
Select * from Emp where deptno = p_deptno;
Cursor with Parameters
Changes in Open
Open Cur_name(parameter1 , parameter2 ) ;


Example:
Open c_emp(10); This will pass deptno 10 to query so it will execute for
deptno 10

Open c_emp(20); This will pass deptno 20 to query so it will execute for
deptno 20

Thus cursor becomes more dynamic and flexible.

Same cursor can be used for different value in where
condition.

Cursor with Parameters
Cursor without parameter

Declare
Cursor c_emp IS
Select * from Emp where deptno = 10;

V_emp c_emp%Rowtype;

Begin
Open c_emp
Loop
<Code>
End Loop;
End;

This cursor can only run for deptno
10 always.
Cursor with parameter

Declare
Cursor c_emp (p_deptno number) IS
Select * from Emp where deptno =
p_deptno;
V_emp c_emp%Rowtype;

Begin
Open c_emp(10); -- or Open c_emp(20)
Loop
<Code>
End Loop;
End;

This cursor can run for any deptno
whichever is passed during open ,
10 , 20 anything.

Example
Example 29 Sample29.SQL

Example 30 Sample30.SQL


Cursor - For Update of Where Current of
For update of clause provides locks on the rows of the
query in the cursor.

Because of this lock nobody else can refer to those rows
till your cursor is closed.

Advantage is no two people will get the same rows to
access since one has already locked it.

Disadvantage is till first person releases the lock the
second one cannot get the data in those rows.
Cursor - For Update of Where Current of
This type of cursor is used when we want
to update the record along with the Fetch.

To update
Cursor declaration should have For update of
in the end.
Update statement in the Begin block should
have Where Current of clause.

Cursor - For Update of Where Current of
Example

Declare
Cursor c_emp IS
Select * from Emp where deptno= 10
For update;

v_emp c_emp%rowtype;

Begin
For v_emp in c_emp
Loop
Update Emp set sal = sal + (sal * 0 .1) where current of c_emp;
End Loop;

End;

Cursor - For Update of Where Current of
Example : You can also say For update of column name instead of just for
update. This makes it more readable else logically there is no other difference.

Declare
Cursor c_emp IS
Select * from Emp where deptno= 10
For update of Sal;

v_emp c_emp%rowtype;

Begin
For v_emp in c_emp
Loop
Update Emp set sal = sal + (sal * .1) where current of c_emp;
End Loop;

End;

Cursor - For Update of Where Current of
In the Declaration we can also use NOWAIT .

If suppose we are trying to open a for update of cursor and
rows in that has already been locked by some other program
then our program will keep on trying to execute till other one
releases.

In this case your program can hang.

Using NOWAIT ensures that
if rows are already locked by somebody else then it returns
immediately without doing anything so that your program does
not hang.
If rows are not already locked then it will get the locks on those
rows.
Cursor - For Update of Where Current of
Example : With NOWAIT clause

Declare
Cursor c_emp IS
Select * from Emp where deptno= 10
For update of Sal NOWAIT;

v_emp c_emp%rowtype;

Begin
For v_emp in c_emp
Loop
Update Emp set sal = sal + (sal * .1) where current of c_emp;
End Loop;

End;


Example
Example 31 Sample31.SQL

Ref Cursor
Ref Cursor is actually a kind of data type in
pl/sql.

Basically, it is used to make the concept of
cursor more dynamic.

We can use the same type of cursor for different
query in the same program.
Ref Cursor
Three step process
Declare a Type of Ref Cursor
Declare a variable of that type
Open the cursor by giving the query in the
Begin Section instead of query being given
in the Declare Section.
Ref Cursor
Three step process
Declare
--Step1
Type t_ref_emp IS Ref Cursor;

--Step2
c_emp t_ref_emp;

Begin
--Step3
Open c_emp for Select * from Emp;
End;

As seen in step 3 query is given in Begin Section instead of Declare.
Ref Cursor

Declare

Type t_ref_emp IS Ref Cursor;

c_emp t_ref_emp;

v_query char(200);

Begin

v_query := &Query;

--Step3
Open c_emp for v_query
End;

As seen in step 3 we are accepting a query from user in Begin
Section and different query can be given , so program can work
with different types of Query.
Example
Example 32 Sample32.SQL


Example 33 Sample33.SQL
Exception Handling
When an exception or Error occurs in a PL/SQL block,
its execution section (Begin) immediately terminates.

Control is passed to the exception section.

Once the control is passed to exception section then it is
handled there and after that program terminates.

Every exception in PL/SQL has an error number and
error message, all exceptions also have names.
Exception Handling
Error Handling or Exception Handling is
required because at run time if some
problem occurs with the program we
should have provision to safely end the
program

With either proper message or action
rather than ending up in uncontrolled
situation.
Exception Handling
Exception can be System defined or User
defined.

In any case, whenever an error occurs, an
exception is raised

Raised exception has some number or
name associated to it. We can handle the
error in the EXCEPTION section of
program using this no. and name of error.
Exception Handling
Three ways we can handle
exception in PL SQL are:
System Defined Exception
Associating with System Defined
Exception
User Defined Exception

Exception Handling
System Defined Exception : Oracle has identified certain cases in
which error can come in a program. It has given number and name
to those cases.

Whenever that condition occurs in a program oracle raises an
exception.

It is the job of the programmer to right the code to handle such
cases in their own ways

After finishing the code in Exception it will terminate the program. i.e
Once an error occur then no further code in the begin section is
processed. You need to Re run the program then.
Exception Handling
Few examples of such cases

Exception Name Oracle Error
value
SQLCODE( value
we get at runtime)
INVALID_CURSOR ORA-01001 -1001
INVALID_NUMBER ORA-01722 -1722
NO_DATA_FOUND ORA-01403 -1403
ZERO_DIVIDE ORA-01476 -1476
Exception Handling
Remember, there are thousands of such errors and one
cannot handle all of them in code , while making program
we come to know what all error cases can come so we
need to handle those only.

Example :
If in a program we are dividing two numbers : m/n
if n is 0 then it will be a infinity or zero divide error so
we will handle Zero_Divide Exception.

If in a program we are writing a query
Select ename into v_name from Emp where Empno = v_empno;
Suppose that empno is not in the table then we will not get any
row so we will have No_Data_found Exception and we need to
handle that.
Exception Handling
Declare
m number;
n number;
x number;

Begin

m := &number1;
n := &number2;

x := m/n ;
dbms_output.put_line( Output is : || x);
End;

In this program if we take n as 0 then infinity error can come. So we
need to handle that.
Exception Handling

Declare
m number;
n number;
x number;
Begin
m:= &number1;
n:= &number2;
x := m/n ;
dbms_output.put_line('Output is : ' || x);

EXCEPTION
WHEN ZERO_DIVIDE then
dbms_output.put_line('Infinity Error , you cannot enter value 0 for second
number');
dbms_output.put_line(' Try again with Proper value');
End;
Exception Handling
To handle multiple exception in the same program.

EXCEPTION
WHEN ZERO_DIVIDE then
dbms_output.put_line( Try again with Proper value);
WHEN INVALID_NUMBER then
dbms_output.put_line( Number entered is invalid);
WHEN VALUE_ERROR then
dbms_output.put_line( Invalid value);
End;


Exception Handling
To handle all the exception in the same program.

EXCEPTION
WHEN ZERO_DIVIDE then
dbms_output.put_line( Try again with Proper value);
WHEN INVALID_NUMBER then
dbms_output.put_line( Number entered is invalid);
WHEN OTHERS then
dbms_output.put_line( Some Error occurred , contact administrator);
End;

When others handles all the other errors other then specified on top
of it. So here all other errors other then ZERO_DIVIDE and
INVALID_NUMBER will get the message given in WHEN OTHERS.
Exception Handling
SQLCODE This function when used in EXCEPTION section returns
the error number.

SQLERRM : This function when used in EXCEPTION section returns
the error message.

This two functions can be used in WHEN OTHERS section to know the
exact error number and its message whenever any error occurs.

EXCEPTION
WHEN ZERO_DIVIDE then
dbms_output.put_line( Try again with Proper value);
WHEN INVALID_NUMBER then
dbms_output.put_line( Number entered is invalid);
WHEN OTHERS then
dbms_output.put_line( Error number is : || SQLCODE);
dbms_output.put_line( Error message is : || SQLERRM);

End;
Exception Handling
In all the previous cases here we have displayed different
messages while handling different exceptions but we can
do other things also to handle exception (Few such things
are given below)

Example :

We can write the problem in a file.
We can reset or change the values in some variables.
We can insert that error no and error message along with date and
time in some table so that all the error occurring can be seen in
future.
Example
Example 34 Sample34.SQL

Example 35 Sample35.SQL

Example 36 Sample36.SQL

Example 37 Sample37.SQL

Example 38 Sample38.SQL


Associating with Pre-Defined Exception
Sometimes we want to give more meaningful name or rather name
suitable to us to the error number.

To accomplish this we can associate a new name for the error
number.

For example error no : -1 has name DUP_VAL_ON_INDEX this
error occurs when we try to insert a record in a table such that one
of the column is primary key and that value we are passing is
already there. i.e we are trying to violate primary key.

We will give a name DUPLICATE_VALUE in our program.

Associating with Pre-Defined Exception
Two steps:
First we will declare DUPLICATE_VALUE as an Exception in
Declare Section
We will use function EXCPETION_INIT to associate this name with
the Error number.

EXCEPTION_INIT is a function that we will have to call in Declare
section only.

Secondly, this type of association should happen at compilation time
only so will have to use PRAGMA.

PRAGMA is compiler directive i.e. it helps in calling or associating
something before the program actually runs.
Associating with Pre-Defined Exception
Declare
DUPLICATE_VALUE Exception ;
PRAGMA Exception_Init (DUPLICATE_VALUE , -1);

Begin
<CODE>
Exception
When DUPLICATE_VALUE then
<Message or any other error handling code>
End;
Example
Example 39 Sample39.SQL



User Defined Exception
Oracle has identified more than 20,000 Exceptions which can occur
in a program.

There can still be an error case where user feel that particular case
is an error case though it may not be an errors for others.

Example:
In banking if balance in an account is less then 500 then its an
error but value less then 500 in other case or for oracle it is not a
error.

In Employee data Salary cannot be 0 its an error data but having
value equal to 0 in salary column is not an error for oracle.
User Defined Exception
User Defined Exception Handling is thus used for all
such cases.

In user defined exception handling you need to do three
thing:
Declare an Exception Declare Section
Raise an Exception - Begin Section
Handle an Exception Exception section
User Defined Exception
Handling part is same as System defined section but
Declare and Raise is required since oracle does not
have any such error case.

We need to declare so that our new error has name.

We need to Raise because oracle does not know when
that error will occur in Begin section , we need to decide
and call that at right time.
User Defined Exception
Declare
Invalid_Salary Exception; --Declaring an Exception

v_empno Emp.empno%type;
v_sal Emp.sal%type;

Begin
v_sal := &Salary; -- Accepting new salary from user
v_empno := &empno;

if v_sal < 1000 then
--If salary is less then 1000 then it is error for us
Raise Invalid_Salary; --Raising an exception
End if;

Update Emp set sal = v_sal where empno = v_empno;

Exception
When Invalid_Salary then
dbms_output.put_line (Salary cannot be less then 1000 );
End;
-- See next slide

User Defined Exception
In the program if salary entered is less than 1000 then
Exception will be raised & updation will be stopped.

If salary is not less than 1000 then Exception will not be
raised and so next line i.e updation will take place in the
table.


Example
Example 40 Sample40.SQL





RAISE_APPLICATION_ERROR
This function is also used sometime to handle errors in
pl/sql.

In the code where ever this function is called program
ends there only.

No line of code after that is executed.

This is not frequently used as it is not a structured way to
handler errors but at times it is one of the good options
to use. It is used frequently in triggers ( We will see in
fourth day session).
RAISE_APPLICATION_ERROR
RAISE_APPLICATION_ERROR (Error Number , Error Message);

Error Number can be anything between : -20,001 to -20999

As first 20,000 numbers are reserved by Oracle System defined
exceptions.

Error Message is the message user will see before program will
end.

Same error number can be used for different message in different
programs.

Example :
RAISE_APPLICATION_ERROR (-20010 ,Salary is not valid);
RAISE_APPLICATION_ERROR (-20001 ,In sufficient balance);
RAISE_APPLICATION_ERROR (-20001 , Deptno does not exist);
Example
Example 41 Sample41.SQL




Summary
We saw today

Record type and its uses
Table type and its uses
Cursor concept , types (Implicit, Explicit) and use.
Exception Handling. (System and User Defined..)



Thank you !!
Next session tomm
Stored procedures Procedure ,
Function and Package

You might also like