cursor and exception handling by nidhi bhatnagar

55
Cursor and Exception Handling By Nidhi Bhatnagar

Upload: anthony-townsend

Post on 27-Dec-2015

224 views

Category:

Documents


0 download

TRANSCRIPT

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 processStep1 : Declare a cursorStep2 : 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;

BeginFor v_emp in c_empLoop

dbms_output.put_line(v_emp.empno || ‘ ‘ || v_emp.sal);End Loop;

End;

Cursor with For Loops

For Loop automatically:Open a cursorFetch 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_nameLOOP      {.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;

BeginOpen c_empLoop<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;

BeginOpen 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

DeclareCursor c_emp IS

Select * from Emp where deptno= 10 For update;

v_emp c_emp%rowtype;

BeginFor v_emp in c_empLoop

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.

DeclareCursor c_emp IS

Select * from Emp where deptno= 10 For update of Sal;

v_emp c_emp%rowtype;

BeginFor v_emp in c_empLoop

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

DeclareCursor c_emp IS

Select * from Emp where deptno= 10 For update of Sal NOWAIT;

v_emp c_emp%rowtype;

BeginFor v_emp in c_empLoop

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--Step1Type t_ref_emp IS Ref Cursor;

--Step2c_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’;

--Step3Open 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);

EXCEPTIONWHEN ZERO_DIVIDE thendbms_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 thendbms_output.put_line(‘ Try again with Proper value’);

WHEN INVALID_NUMBER thendbms_output.put_line(‘ Number entered is invalid’);

WHEN VALUE_ERROR thendbms_output.put_line(‘ Invalid value’);

End;

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

EXCEPTION

WHEN ZERO_DIVIDE thendbms_output.put_line(‘ Try again with Proper value’);

WHEN INVALID_NUMBER thendbms_output.put_line(‘ Number entered is invalid’);

WHEN OTHERS thendbms_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.

EXCEPTIONWHEN ZERO_DIVIDE then

dbms_output.put_line(‘ Try again with Proper value’);

WHEN INVALID_NUMBER thendbms_output.put_line(‘ Number entered is invalid’);

WHEN OTHERS thendbms_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 ExceptionDeclare 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 usRaise Invalid_Salary; --Raising an exception

End if;

Update Emp set sal = v_sal where empno = v_empno;

ExceptionWhen 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