Вы находитесь на странице: 1из 54

PL/SQL:

-------
Features:
---------
-> it executes a block of statements as a unit.
-> it supports control structures and iteration control statements.
-> it supports exception handling
-> pl/sql supports automatic execution of code, through db triggers
-> pl/sql supports sub-programs(procedures and functions)
-> pl/sql supports packages.
-> it supports to share the programs from one user to another user and it supports diffrerent appl.
software tools.

Block:
------
-> it is a collection of sql and non-sql statements.
-> there are two types of blocks.
1. Anonymous Block
2. Named Block

1. Anonymous Block:
------------------
-> this block of statements are not stored in db permanently,
it is stored in SQL BUFFER.
SQL BUFFER: it is a temporary buffer, and it holds last executed query.
-> to save anonymous block programs, user can explicitely save it by using save command.

2. Named Block:
---------------
-> this block of statements are stored in db permanently.
ex: Triggers, Procedures, Functions & Packages

PL/SQL BLOCK STRUCTURE:


----------------------
[ Declare
<variable declaration>;]
Begin
<exec-statements>;
[ Exception
<exec-statements>;]
End;

Simple Block:
------------
Begin
<exec-statements>;
End;
pl/sql supports DML,DRL & TCL Commands.
pl/sql not supported DDL & DCL Commands.

how to declare the variable:


---------------------------
tempno number(4);
name varchar2(10);
i number(2):=1;
doj date default sysdate;
pi constant number(5,3):=3.143;
-> pl/sql supports all sql datatypes and it supports BOOLEAN Datatype.

BOOLEAN:
-------
-> this datatype stored either TRUE or FALSE.
ex: Flag Boolean:=TRUE/FALSE;

:=
---
-> it is an assignment operator, used to assign the values into given variable.
ex: a:=10; (10 value is assigned to 'a' variable)

comments:
---------
-> comments are description of the given statement.
-> comments are non-executable statements.
-> there are two types of comments.
1. single line comment
2. Multi line comment

1.single comment:
----------------
-> comment contains single line is called as single line comment.
-> single line comments are represented with '--'
EX: -- pl/sql block for to display welcome message

2. Multi line comment:


----------------------
-> comment contains morethan one line is called as multi-line comment.
-> multiline comments are represented with

/* - - - - - -
- - - - - - - */
DBMS_OUTPUT.PUT_LINE(Arg1):
--------------------------
-> it is one of the output statement.
-> it returns output to sql buffer
-> it accepts only one argument at a time.
ex: dbms_output.put_line('welcome to pl/sql');

SET SERVEROUTPUT ON:


-------------------
-> it displays output from sql buffer to output screen.
-> it is session valid.

example:

-- write a pl/sql block to display welcome message.

Begin
dbms_output.put_line('welcome to World');
End;

-- Write a pl/sql block to add two numbers.

Declare
a number(2):=10;
b number(2):=20;
Begin
dbms_output.put_line((a+b));
End;

Declare
a number(2):=&a;
b number(2):=&b;
Begin
dbms_output.put_line((a+b));
End;

Declare
a number(2):=&a;
b number(2):=&b;
Begin
dbms_output.put_line('Sum of Two Numbers = '||(a+b));
End;
-> write a pl/sql block to accept employee number and display corresponding employee details.
Begin
SELECT EMPNO,ENAME,SAL,DEPTNO FROM EMP WHERE EMPNO=7788;
End;
select..into:
-------------
-> used to copies database column vlaues into pl/sql variables.
-> no.of db columns must be matched with no.of pl/sql variables and corresponding datatype should be
matched.

syntax:
-------
select columm1,column2,... into variable1, variable2,... from <table_name>
where <condition>;
ex:
---
select empno,ename,sal,deptno into tempno,tename,tsal,tdeptno from emp
where empno=7788;

example:
--------
Declare
tempno number(4);
tename varchar2(10);
tsal number(8,2);
tdeptno number(2);
Begin
select empno,ename,sal,deptno into tempno,tename,tsal,tdeptno from emp
where empno=&empno;
dbms_output.put_line(tempno||' '||tename||' '||tsal||' '||tdeptno);
End;

Declare
tempno number(4);
tename varchar2(10);
tsal number(7,2);
tdeptno number(2);
Begin
select empno,ename,sal,deptno into tempno,tename,tsal,tdeptno from emp
where empno=&empno;
dbms_output.put_line(tempno||' '||tename||' '||tsal||' '||tdeptno);
End;

Attributes:
----------
-> used to declare variable datatype dynamically according to specified structure.
-> basically there are two types of attributes.
i. column type attribute
ii. rowtype attribute
i.column type attribute:
-----------------------
-> used to declare variable datatypes dynamically according to specified table of column structure.
syntax:
-------
<variable_name> <table_name>.<column_name>
ex:
Tempno Emp.Empno%type;
Tsal Emp.Sal%type;

Example:
--------
Declare
tempno emp.empno%type;
tename emp.ename%type;
tsal emp.sal%type;
tdeptno emp.deptno%type;
Begin
select empno,ename,sal,deptno into tempno,tename,tsal,tdeptno from emp
where empno=&empno;
dbms_output.put_line(tempno||' '||tename||' '||tsal||' '||tdeptno);
End;

ii. rowtype attribute or table type attribute:


---------------------------------------------
-> used to declare variable datatype dynamically according to specified table structure.

syntax:
-------
<variable_name> <table_name>%rowtype;

ex:

Erec Emp%rowtype;

'Erec' is a record type variable and it holds one record at a time.

Example:
--------
Declare
E Emp%rowtype;
Begin
Select * into E from Emp where empno=&empno;
dbms_output.put_line(e.empno||' '||e.ename||' '||e.job||' '||e.hiredate||' '||e.sal||' '||e.deptno);
End;
-- write a pl/sql block to display netsalary for a given employee number.
Declare
Tempno Emp.Empno%type:=&Tempno;
Tsal Emp.Sal%type;
Tcomm Emp.Comm%type;
Netsal Number;
Begin
select Sal,Comm into Tsal,Tcomm From Emp
where Empno=Tempno;
Netsal:=Tsal+Nvl(Tcomm,0);
Dbms_output.put_line('Employee Number : '||Tempno);
Dbms_output.put_line('Employee Basic Salary : '||TSal);
Dbms_output.put_line('Employee Commission : '||Nvl(Tcomm,0));
Dbms_output.put_line('Employee Net Salar : '||Netsal);
End;

Control Structures:
-------------------
-> used to control flow of the program.
-> there are three types of control structures.

I. Conditional Control Structures


i. Simple if
ii. if..else
iii. nested if
iv. if..else lader

II. Branching Control Structures


i. Case

III. Iteration Control Structures


i. simple loop
ii. while loop
iii. for loop
iv. for cursor

I. Conditional Control Structures


i. Simple if:
------------
-> it contains only true block.
syntax:
-------
if <condition> then
<exec-statements>; -- true block
End if;
Example:
--------
Declare
flag Boolean:=&flag;
Begin
if Flag=True then
dbms_output.put_line('We r in True Block.');
end if;
dbms_output.put_line('End of the Program.');
End;

ii. if..else:
------------
if <condition> then
<exec-statements>; -- true block
else
<exec-statements>; -- false block
end if;

example:
--------
-- write a pl/sql block to display given no. is even or odd.

Declare
Num Number(3):=&Num;
Begin
if Mod(Num,2)=0 then
dbms_output.put_line('Given No. is Even.');
else
dbms_output.put_line('Given No. is Odd.');
end if;
End;

iii. nested if:


---------------
-> if within the if is called as nested if.

syntax:
-------
if <condition> then
if <condition> then
<exec-statement>;
else
<exec-statements>;
end if;
else
if <condition> then
<exec-statement>;
else
<exec-statements>;
end if;
end if;

example:
--------
-- pl/sql block for to display biggest of three numbers.

a b c

Declare
a number(2):=&a;
b number(2):=&b;
c number(2):=&c;
Begin
if a>b then
if a>c then
dbms_output.put_line('A is Big.');
else
dbms_output.put_line('C is Big.');
end if;
else
if b>c then
dbms_output.put_line('B is Big.');
else
dbms_output.put_line('C is Big.');
end if;
end if;
End;

iv. if..else Lader:


------------------
syntax:
-------
if <condition> then
<exec-statements>;
elsif <condition> then
<exec-statements>;
elsif <condition> then
<exec-statements>;
......................

else
<exec-statements>;
end if;
Example:
--------
-- pl/sql block for to display student grades.

Declare
tavg Number(7,2):=&Tavg;
Begin
if tavg>=70 then
dbms_output.put_line('Grade A.');
elsif tavg>=60 then
dbms_output.put_line('Grade B.');
elsif tavg>=50 then
dbms_output.put_line('Grade C.');
else
dbms_output.put_line('Grade D.');
end if;
End;

II. Branching Control Sturctures:


---------------------------------
i. Case

syntax:
-------
Case <variable/Expression>
when <constant> then
<exec-statements>;
when <constant> then
<exec-statements>;
when <constant> then
<exec-statements>;
else
<exec-statement>;
end case;

example:
--------
Declare
color Varchar2(1):='&color';
Begin
case color
when 'r' then
dbms_output.put_line('u r selected Red Color.');
when 'y' then
dbms_output.put_line('u r selected Yellow Color.');
when 'b' then
dbms_output.put_line('u r selected Blue Color.');
else
dbms_output.put_line('u r selection is wrong, plz. try again!!!!!');
end case;
End;

III. Iteration Control Structures:

Iteration Control Statements:


-----------------------------
i. Simple Loop
ii. While Loop
iii. for loop
iv. for cursor

i. Simple Loop:
---------------
-> it is an infinite loop.
syntax:
-------
Loop
<exec-statements>;
End Loop;

example:
--------
Begin
Loop
dbms_output.put_line('Welcome');
End Loop;
End;

to break simple loop:


--------------------
syntax1:
--------
if <condition> then
exit;
end if;

example:
-------
Declare
i Number(2):=1;
Begin
Loop
if i<=10 then
dbms_output.put_line('Welcome');
else
exit;
end if;
i:=i+1;
End Loop;
End;

syntax2:
--------
EXIT when <condition>;

example:
-------
Declare
i Number(2):=1;
Begin
Loop
Exit when i>10;
dbms_output.put_line('Welcome');
i:=i+1;
End Loop;
End;

ii. While Loop:


--------------
Syntax:
-------
While <condition>
Loop
<exec-statements>;
<incre/decre>;
End Loop;

Example:
-------
-- write a pl/sql block to print first 10 natural numbers.

Declare
i Number(2):=1;
Begin
while(i<=10)
Loop
dbms_output.put_line(i);
i:=i+1;
End Loop;
End;
-- write a pl/sql block to print multiplication table.
5*1=5
5*2=10
.
.
5*10=50

Declare
N Number(2):=&N;
i Number(2):=1;
Begin
While(i<=10)
Loop
dbms_output.put_line(N||'*'||i||'='||(N*i));
i:=i+1;
End Loop;
End;

-- print 1..10 numbers in reverse order

Declare
i Number(2):=10;
Begin
while(i>=1)
Loop
dbms_output.put_line(i);
i:=i-1;
End Loop;
End;

iii. For Loop:


-------------
-> by default it is incremented by 1.
syntax:
-------
for <index_variable> in <start_value>..<end_value>
Loop
<exec-statements>;
End Loop;

Example:
-------
Begin
for i in 1..10
loop
dbms_output.put_line(i);
end loop;
End;
-- in reverse order
Begin
for i in Reverse 1..10
loop
dbms_output.put_line(i);
end loop;
End;

CURSORS:
--------
Declare
e emp%rowtype;
Begin
select * into e from emp where DEPTNO=&DEPTNO;
dbms_output.put_line(e.empno||' '||e.ename||' '||e.sal||' '||e.deptno);
End;

Cursors:
-------
-> it is one of the private context area.
-> it creates a temporary buffer
-> it is created by using select statement output.
-> it is not stored in db permanently.
-> in pl/sql block whenever select statement returns morethan one record, on that time we are using
cursors concept.
-> basically cursors are two types.
I. Static Cursor
i. Explicit Cursors
ii. Implicit Cursors
II. Dynamic Cursor

I. Static Cursor
i. Explicit Cursors:
--------------------
-> it is created by User

cursor Operations:
-----------------
i. Declaring the Cursor:
-----------------------
-> in declaration part we can declare the cursor
syntax:
------
cursor <cursor_name> is <select statement>;
ii. Open <cursor_name>:
----------------------
-> it opens the cursor
-> Memory is allocated, After opened.

iii. Fetch <cursor_name> into <pl/sql variables>:


-------------------------------------------------
-> it fetches data from cursor into pl/sql variables;
-> it fetches one row a time.

iv. Close <cursor_Name>:


-----------------------
-> it closses the cursor
-> allocated memory will be de-allocated.

cursor Attributes:
-----------------
-> it shows status of the cursor
-> it returns boolean value.

syntax:
-------
<cursor_name>%<attribute>;

a. %isopen:
----------
-> it returns true, when the cursor opens successfully.

b. %found:
----------
-> it returns true, when the cursor contains data.

c. %notfound:
-------------
-> it returns true, when the cursor doesn't find any data.

d.%rowcount:
------------
-> it returs number.
-> no.of fetch statements executed.

Example:
--------
Declare
cursor my_cur is select empno,ename,sal,deptno from emp;
tempno emp.empno%type;
tename emp.ename%type;
tsal emp.sal%type;
tdeptno emp.deptno%type;
Begin
Open my_cur;
if my_cur%isopen then
dbms_output.put_line('cursor opens successfully.');
end if;
fetch my_cur into tempno,tename,tsal,tdeptno;
dbms_output.put_line(tempno||' '||tename||' '||tsal||' '||tdeptno);
fetch my_cur into tempno,tename,tsal,tdeptno;
dbms_output.put_line(tempno||' '||tename||' '||tsal||' '||tdeptno);
fetch my_cur into tempno,tename,tsal,tdeptno;
dbms_output.put_line(tempno||' '||tename||' '||tsal||' '||tdeptno);
Close my_cur;
End;

cursors using Simple Loop:


-------------------------
Declare
cursor my_cur is select empno,ename,sal,deptno from emp;
tempno emp.empno%type;
tename emp.ename%type;
tsal emp.sal%type;
tdeptno emp.deptno%type;
Begin
Open my_cur;
if my_cur%isopen then
dbms_output.put_line('cursor opens successfully.');
end if;
Loop
fetch my_cur into tempno,tename,tsal,tdeptno;
Exit when my_cur%notfound;
dbms_output.put_line(tempno||' '||tename||' '||tsal||' '||tdeptno);
End Loop;
Close my_cur;
End;

cursors using while looP;


------------------------
Declare
cursor my_cur is select empno,ename,sal,deptno from emp;
tempno emp.empno%type;
tename emp.ename%type;
tsal emp.sal%type;
tdeptno emp.deptno%type;
Begin
Open my_cur;
if my_cur%isopen then
dbms_output.put_line('cursor opens successfully.');
end if;
Fetch my_cur into Tempno,Tename,Tsal,Tdeptno;
while(my_cur%found)
Loop
dbms_output.put_line(tempno||' '||tename||' '||tsal||' '||tdeptno);
fetch my_cur into tempno,tename,tsal,tdeptno;
End Loop;
Close my_cur;
End;

--> write a cursor program to print first five max. salaries employee details.
--> write a cursor to displa alternative records.(even or odd records)
-> Create table Library Database with Book_id, Book_name, Author and Stock.

validations:
------------
-> Book_id should be generated automatically..
-> Book_name is Capital Letters
-> Author name is Initial Capital Letter
-> Min. Stock 1 and Max. Stock 10 should be accepted.

Create a Student Database with Sno, sname, Class, Book_id, No.of issued BOOKS
,Issue Date, Return Date.

Validations:
-----------
-> Sname is Capital Letters.
-> Class should be accept only 1 t0 10.
-> Book_id must be present in Library.
-> min. and max. No.of book issue to student only 1.
-> Date of issue is not Grater than System date and Not Less than System date.
-> Date of Return Should Grater than or equal to Date of Issue.
-> if Book is Issuing or returning stock should be updated.

Create a Library Database:


-------------------------
Create table Library(Book_Id Number(2), Book_Name Varchar2(10),
Author Varchar2(10), Stock Number(2));

Trigger:
-------
Trigger Event: Before Insert
Trigger Name: Lib_Before_insert
Trigger type: Row Level Triggers
Table Name: Library
Create or Replace Trigger Lib_Before_Insert
Before Insert on Library
for each row
begin
Select Nvl(Max(Book_id),0)+1 into :new.book_id from Library;
:new.book_name:=upper(:new.book_name);
:new.Author:=initcap(:new.author);
if :new.stock not between 1 and 10 then
raise_application_error(-20001,'Stock Accepts only 1 to 10.');
end if;
End;

Create a Student Database:


-------------------------
Create Table Student(Sno Number(2), Sname Varchar2(10),
Class Number(2),book_id Number(2),
issued_books number(2), doi date, dor date);

Triggers:
---------
Trigger Event: Before Insert
Table Name: Student
Trigger Name: stu_before_insert

Create or Replace Trigger stu_before_insert


Before Insert on Student
for each row
declare
cnt number;
Begin
:new.sname:=upper(:new.sname);
if :new.class not between 1 and 10 then
raise_application_error(-20001,'class accepts only 1 to 10 only.');
end if;
select count(book_id) into cnt from Library where book_id=:new.book_id;
if cnt=0 then
raise_application_error(-20002,'Invalid Book Number...');
end if;
if :new.issued_Books!=1 then
raise_application_error(-20003,'min. and max. no.of issuing books only 1.');
end if;
if to_char(:new.doi,'dd/mm/yy')!= to_char(sysdate,'dd/mm/yy') then
raise_application_error(-20004,'Date of Issue Must be System Date.');
end if;
End;
Trigger Event: After Insert
Table Name: student
Trigger Name: stu_After_Insert

Create or Replace Trigger Stu_After_Insert


after Insert on Student
for each row
begin
Update Library set stock=stock-:new.issued_books where book_id=:new.book_id;
end;

Trigger Event: Before Update


Table Name: Student
Trigger Name: stu_before_update

Create or Replace Trigger stu_before_update


before update on student
for each row
begin
if to_char(:new.dor,'dd/mm/yy')<to_char(:new.doi,'dd/mm/yy') then
raise_application_error(-20001,'Date of Issue must be Grater than or Equal to Date of Isssue');
end if;
End;

Trigger Event: After Update


Table Name: Student
Trigger Name: Stu_after_Update

Create or Replace Trigger Stu_after_update


after update on Student
for each row
begin
update library set stock=stock+:new.issued_books where book_id=:new.book_id;
end;

-> All Triggers are stored in User_Triggers(system table).

select trigger_Name from user_triggers


where table_name='STUDENT';

-> All Named Blocks Programs(triggers, procedures, functions & packages) are stored in
'User_Source'(pre-defined table).
-> to see the trigger body

select Text from User_source where name='STU_BEFORE_INSERT';

Dropping Triggers:
------------------
Drop Trigger <Trigger_name>;

ex:
---
Drop Trigger Stu_Before_insert;

SUB PROGRAMS:
-> A SET OF PL/SQL STATEMENTS STORED PERMANENTLY IN DATABASE AND PERFORMS A TASK.
-> THEY ACCEPT ARGUMENTS WHILE EXECUTION
-> THEY ARE STORED IN 'COMPILED FORMAT';
-> THEY ARE REUSABLE COMPONENTS
-> THEY PROVIDES MODULARITY
MODULARITY
-> A HUGE PROGRAM DEVIDED INTO SUB TASKS
-> EASY TO UNDERSTAND
-> EASY TO DEBUG THE ERRORS

1. PROCEDURES
-> Procedures are may/may not return value
2. FUNCTIONS
-> Functions should return value
Procedure syntax:
Create or Replace Procedure <Procedure_name>
[ (argument mode datatype,....)]
is
<variable declaration>;
Begin
<exec statements>;

[ Exception Block
<exec-statements>; ]
end;

Procedure without paramaters:


-----------------------------
Example1:
---------
Create or Replace Procedure My_Proc
is
Begin
dbms_output.put_line('Welcome to Procedures....');
End My_Proc;
to execute the procedure:
------------------------
2 syntaxes:
-----------
1. Exec <procedure_Name>;
ex: Exec My_Proc;

2. Begin
<procedure_name>;
End;

ex: Begin
my_proc;
End;

-- write a procedure to display sum of two numbers.

Create or Replace Procedure add_proc


is
A Number:=10;
B Number:=20;
Begin
dbms_output.put_line('Sum of Two Numbers = '||(a+b));
End Add_Proc;

Create or Replace Procedure add_proc


is
A Number:=&A;
B Number:=&B;
Begin
dbms_output.put_line('Sum of Two Numbers = '||(a+b));
End Add_Proc;

Procedures with Parameters:


---------------------------
ex:
Create or replace procedure add_proc(a number, b number)
is
begin
dbms_output.put_line('sum of two numbers = '||(a+b));
end add_proc;

to execute above procedure:


--------------------------
Exec Add_Proc(10,60);
Exec Add_Proc(&a,&b);
-- write a procedure to accept Employee Number and display Corresponding Employee Net Salary.

Create or Replace procedure Emp_Proc(Tempno Emp.Empno%type)


is
Tsal Emp.Sal%type;
Tcomm Emp.Comm%type;
Netsal Number;
Comm_Null Exception;
Begin
Select Sal,Comm into Tsal,Tcomm from Emp where Empno=Tempno;
if Tcomm is Null then
Raise Comm_Null;
end if;
Netsal:=Tsal+Tcomm;
dbms_output.put_line('Given Employee Net Salary = '||Netsal);
Exception
When Comm_Null then
Raise_Application_error(-20001,'Given Employee is Not getting Commission.');
when No_data_found then
Raise_application_error(-20002, 'Such Employee Number is Not Exist.');
End Emp_Proc;

Procedures Return values through Parameter Modes:


-------------------------------------------------
-> there are three types of parameters modes.
IN -> it accepts input into Sub-Program(default)
OUT -> it returns output through sub-program
IN OUT -> BOTH.

ex: IN
-------
Create or replace procedure add_proc(a in number, b in number)
is
begin
dbms_output.put_line('sum of two numbers = '||(a+b));
end add_proc;

exec Add_proc(90,30);

ex: OUT :
----------
Create or replace procedure add_Proc(A in Number, B in Number, C out Number)
is
Begin
C:=A+B;
End add_proc;
to execute above procedure two methods:
---------------------------------------
1. on Sql prompt:
-----------------
sql> Var res Number;

-> to declare variables on sql prompt those variables are called as Global Variables/Bind variables/sql
buffer variables.
-> bind variables are represented with ':' operator.

sql> exec add_proc(20,50,:res);

sql> Print :res;

2. method: using pl/sql block.


------------------------------
Declare
result Number;
Begin
add_proc(&a,&b,result);
dbms_output.put_line('Sum of two Numbers = '||Result);
End;

-> Above pl/sql block is called as Calling Procedure.

3. IN OUT:
----------
Create or Replace Procedure Add_proc(a in out number)
is
Begin
a:=a*a*a;
End add_proc;

sql> variable a Number;

To assign value into Bind variable(a);

sql> Exec :a:=10;

sql> Exec Add_proc(:a);

ABC Corporation limited,


Hyd.
Enter a Value : ___40_____ Enter b Value: ____80_____

Result: ___120_____

Cal Exit

cal -> add_proc(t1.txt,t2.txt,t3.txt);

Create or replace procedure add_Proc(A in Number, B in Number, C out Number)


is
Begin
C:=A+B;
End add_proc;

-> All Procedures Names are stored in User_objects.

select object_name from user_objects;

select object_name from user_objects where object_type='PROCEDURE';

-> Procedure Bodies are stored in User_Source.

select text from user_source where name='EMP_PROC';

Dropping Procedures:
--------------------

Drop Procedure <procedure_name>;

ex: Drop Procedure my_proc;

-- write a procedure to display Even/odd Records.

'EVEN' or 'ODD'

void main()
{
a=10;b=20;
add(a,b);

}
add(int x, int y)
{
p(x+y);
};

Function Syntax :

Create or Replace Function <function_name>


[(arguments mode datatype,....) ]
RETURN <data_type>
is
<variable declaration>;
Begin
<exec-statements>;
RETURN(VALUE);
[Exception Block
<exec-statements>;
RETURN(VALUE) ]

End;
Create or Replace Procedure Emp_Proc(Temp Varchar2)
is
cursor Emp_cur is select * from emp;
e emp%rowtype;
begin
open Emp_cur;
Loop
fetch Emp_cur into e;
exit when Emp_cur%notfound;
if temp='even' and mod(emp_cur%rowcount,2)=0 then
dbms_output.put_line(emp_cur%rowcount||' '||e.empno||' '||e.ename||' '||e.sal||'
'||e.deptno);
elsif temp='odd' and mod(emp_cur%rowcount,2)=1 then
dbms_output.put_line(emp_cur%rowcount||' '||e.empno||' '||e.ename||' '||e.sal||'
'||e.deptno);
end if;
End Loop;
End Emp_proc;

procedures returns multiple values through out parameters:


---------------------------------------------------------------------------
Create or Replace Procedure my_proc(Tempno in Emp.Empno%type,
e out Emp%rowtype,
status out varchar2)
is
begin
select * into e from emp where empno=Tempno;
Status:='Employee Record Found';
Exception
when no_data_found then
status:='Employee Record Not Found!';
End my_proc;

PL/SQL BLOCK:
-------------
Declare
E Emp%rowtype;
status varchar2(50);
Begin
my_proc(&Empno,E,Status);
dbms_output.put_line(Status);
dbms_output.put_line(e.empno||' '||e.ename||' '||e.job||' '||e.sal||' '||e.deptno);
End;

EXAMPLE:
--------
Create or Replace Procedure Dept_Proc(Tdeptno Number,
Tdname Varchar2,
Tloc Varchar2)
is
begin
insert into Dept values(Tdeptno,Tdname,Tloc);
End Dept_proc;

Notations:
----------
-> there are two types of notations.
i. positional Notations
ii. Named Notations.
i. positional Notations:
------------------------
-> to pass the arguments according their argument positions while executing the program.

ex: Exec Dept_Proc(50,'Eco','Hyd');

ii. Named Notations:


--------------------
-> to pass the arugments values to procedure using their format arugment names while executing the
program.
ex: Exec Dept_Proc(tdname=>'Maths',tloc=>'Sec',tdeptno=>60);

User Defined Functions:


----------------------
-> it is created by user explicitely.
syntax:
-------

Create or Replace Function <function_Name>[(argument Mode Datatype,


argument Mode Datatype,....)]
Return <datatype>
is
<variable declaration>;
Begin
<exec-statements>;
return <value>;
Exception
<exec-statements>;
Return <value>;
End <function_name>;

Functions return Number:

1. user defined functions:


--------------------------
-> these functions are created by user explicitely.
syntax:
-------
Create or replace function <function_name>[(arugment mode datatype,
argument mode datatype,....)]
Return <Datatype>
is
Begin
<exec-statements>;
Return (value);
Exception
<exec-statements>;
Return (value);
End <function_name>;

Function Returns Number Datatype:


---------------------------------
write a function to find simple interest.

Create or Replace Function SI(P Number, T Number, R Number)


Return Number
is
Simple_Int Number;
Begin
Simple_Int:=(P*T*R)/100;
Return (Simple_Int);
End Si;
-> Generally Functions are Executed by using 'SELECT' statement.

Select SI(1000,2,10) from dual;

Function Return Type is Varchar2:


---------------------------------
Create or replace function Emp_Exp(Tempno Emp.Empno%type)
Return Varchar2
is
Tdate Emp.Hiredate%type;
Texp Number;
Begin
select Hiredate into Tdate from Emp
where Empno=Tempno;
Texp:=round((sysdate-tdate)/365);
Return(Tempno||' Employee Experience is '||Texp||' Years.');
Exception
when No_data_found then
Return('Given Employee Record Not Found.');
End Emp_Exp;

SQL> SELECT EMP_EXP(7788) FROM DUAL;

SQL> SELECT EMP_EXP(EMPNO) FROM EMP;

Function Return Type Boolean:


-----------------------------
Create or replace Function Even_Odd(Num Number)
Return Boolean
is
Begin
if Mod(Num,2)=0 then
Return(True);
else
Return(False);
End If;
End Even_Odd;

To execute above function, we can write another pl/sql block.


Begin
if Even_Odd(&Num)=true then
dbms_output.put_line('Given No. is Even.');
else
dbms_output.put_line('Given No. is Odd.');
End if;
End;
write a function to increment Employee Salaries based on their Experiences.
if exp>=30 -> 50%
exp>=25 -> 30%
exp>=20 -> 20%
exp<20 -> 10%

audit_Emp table: empno,ename,job,hiredate,sal,expe,increment_sal,Netsal

Function for to calculate employee Experience:


----------------------------------------------
Create or Replace Function Emp_Expe(Tempno Emp.Empno%type)
return Number
is
Texp number;
Begin
select round((sysdate-hiredate)/365) into Texp from Emp
where empno=Tempno;
Return(Texp);
End Emp_Expe;

Create a table to store incremented Employee Details.


----------------------------------------------------
Create table Audit_Emp(Empno Number(4),Ename VArchar2(10),
Job Varchar2(10), Hiredate Date,
sal Number(7,2), Expe Number(3),
incr_sal Number(7,2),Netsal Number(8,2),
Deptno Number(2));

Procedure for to calculate Increment Salary:


-------------------------------------------
Create or Replace Procedure Emp_Proc
is
Cursor Emp_cur is Select Empno,Ename,Job,Hiredate,Sal,Deptno From Emp;
e emp_cur%rowtype;
texp number;
incr_sal Number;
Begin
Open Emp_cur;
Loop
Fetch Emp_cur into e;
Exit when Emp_cur%notfound;
Texp:=Emp_Expe(e.empno);
if Texp>=30 then
incr_sal:=E.sal*50/100;
elsif Texp>=25 then
incr_sal:=E.sal*30/100;
elsif Texp>=20 then
incr_sal:=E.sal*20/100;
elsif Texp<20 then
incr_sal:=E.sal*10/100;
end if;
insert into Audit_Emp values (e.empno,e.ename,e.job,e.hiredate,e.sal,Texp,
incr_sal,(e.sal+Incr_sal),e.deptno);
End Loop;
dbms_output.put_line(emp_cur%rowcount||' Employees Salaries Incremented.');
End Emp_Proc;

All Functions are stored in user_objects.


All Functions Bodies are stored in 'user_source' system table.
-> to see the function body.
select text from user_source where name='EMP_EXPE';

Dropping Functions:
------------------
Drop Function <function_name>;
Ex:
Drop Function Emp_Expe;

PACKAGES :
It is a collection of Variables, Cursors,
Procedures & Functions are stored in one location.
Easy to share the Subprograms in Application S/w Tools
They Improve performance while accessing subprograms from client location
They are stored in User_Source system table
They supports function Overloading, Encapsulation & Databinding
It has two parts
1. Package Specification :
It holds the declaration of Variables, Cursors & Subprograms
2. Package Body:
It holds the body of subprograms
Packages:
---------
Example:
-------
Package Specification:
---------------------
Create or replace package my_pack
is
Result Varchar2(50); -- public variables
Procedure emp_exp(tempno emp.empno%type);
Function emp_netsal(Tempno Emp.Empno%type) return Varchar2;
End my_pack;
Package Body:
------------
Create or Replace Package Body my_pack
is
Procedure Emp_Exp(Tempno Emp.Empno%type)
is
Tdate Emp.Hiredate%type; -- private variables
Texp Number;
Begin
Select Hiredate into Tdate from Emp where Empno=Tempno;
Texp:=round((sysdate-tdate)/365);
dbms_output.put_line(Tempno||' Employee Experience is '||Texp||'Years.');
End Emp_Exp;

Function Emp_Netsal(Tempno Emp.Empno%type)


return Varchar2
is
Tsal Emp.Sal%type;
Tcomm Emp.Comm%type;
Begin
select sal+nvl(comm,0) into Result From Emp
where empno=Tempno;
Return(Tempno||'Employee Net Salary Rs.'||Result);
End Emp_Netsal;
End my_pack;

TO Execute above Package:


------------------------
Exec my_pack.Emp_Exp(7788);

Select my_pack.Emp_Netsal(7788) from dual;

Function Overloading:
--------------------
Create or Replace Package fo_pack
is
Function addval(a number, b number) return Number;
Function addval(a number, b number, c number) return number;
Function addval(str1 varchar2, str2 varchar2) return Varchar2;
Function addval(str1 varchar2, str2 varchar2, str3 varchar2) return varchar2;
End fo_pack;
Package Body:
-------------
Create or Replace Package Body fo_pack
is
Function addval(a number, b number) return Number
is
Begin
return(a+b);
End addval;

Function addval(a number, b number, c number) return number


is
Begin
return(a+b+c);
End addval;

Function addval(str1 varchar2, str2 varchar2) return varchar2


is
Begin
return(str1||str2);
End Addval;

Function addval(str1 varchar2, str2 varchar2, str3 varchar2) return varchar2


is
Begin
return(str1||str2||str3);
End Addval;

End fo_pack;

Select fo_pack.addval(10,20) from dual;

Select fo_pack.addval('Rama ','Krishna ','Raju') from dual;

Select fo_pack.addval(10,20,50) from dual;

-> all packages bodies are stored in 'user_source'.

-> to see the package body.

select text from USER_SOURCE where name='FO_PACK';

Dropping Packages:
-----------------
Drop Package my_pack;
Packages using Dynamic cursors:
------------------------------
Create or Replace Package p1
is
Type Rcur is Ref Cursor;
End p1;

Procedure:
---------
Create or Replace Procedure my_proc(Tdeptno in Emp.Deptno%type,
my_cur out p1.Rcur)
is
Begin
Open my_cur for Select * from emp where Deptno=Tdeptno;
End my_proc;

pl/sql block:
------------
Declare
my_cur p1.Rcur;
e emp%rowtype;
Begin
my_proc(&tdeptno,my_cur);
Loop
fetch my_cur into E;
exit when my_cur%notfound;
dbms_output.put_line(e.empno||' '||e.ename||' '||e.job||' '||e.sal||
' '||e.deptno);
End Loop;
End;

Create a Bank Database with Accno,customer Name, Account type, Opening Date,Balance.

validations:
------------
-> Account no should be generated automatically(ex: sbi1, sbi2,....)
-> Customer name is capital Letters.
-> Opening date is system date
-> account type should be accepts only either 's' or 'c'
-> if account type is savings then Min. Balance is Rs.500/-
-> if account type is current then min. balance is Rs.1000/-.

Create a bank Transaction table with Transaction Account Number, Transaction Date,
Transaction type and Transaction Amount.
Validations:
-----------
-> Taccount Number should be present in Bank Database.
-> Tdate is System date
-> Transaction type should be accepts either 'D' or 'W'
-> Min. Trasaction Amount is Rs.100/-
-> if the customer applying withdraw, check the available balance.
-> if Customer withdrawing or Depositing amount balance should be updated.

Packages:
---------
Example:
-------
Package Specification:
---------------------
Create or replace package my_pack
is
Result Varchar2(50); -- public variables
Procedure emp_exp(tempno emp.empno%type);
Function emp_netsal(Tempno Emp.Empno%type) return Varchar2;
End my_pack;

Package Body:
------------
Create or Replace Package Body my_pack
is
Procedure Emp_Exp(Tempno Emp.Empno%type)
is
Tdate Emp.Hiredate%type; -- private variables
Texp Number;
Begin
Select Hiredate into Tdate from Emp where Empno=Tempno;
Texp:=round((sysdate-tdate)/365);
dbms_output.put_line(Tempno||' Employee Experience is '||Texp||'Years.');
End Emp_Exp;

Function Emp_Netsal(Tempno Emp.Empno%type)


return Varchar2
is
Tsal Emp.Sal%type;
Tcomm Emp.Comm%type;
Begin
select sal+nvl(comm,0) into Result From Emp
where empno=Tempno;
Return(Tempno||'Employee Net Salary Rs.'||Result);
End Emp_Netsal;
End my_pack;
TO Execute above Package:
------------------------
Exec my_pack.Emp_Exp(7788);

Select my_pack.Emp_Netsal(7788) from dual;

Function Overloading:
--------------------
Create or Replace Package fo_pack
is
Function addval(a number, b number) return Number;
Function addval(a number, b number, c number) return number;
Function addval(str1 varchar2, str2 varchar2) return Varchar2;
Function addval(str1 varchar2, str2 varchar2, str3 varchar2) return varchar2;
End fo_pack;

Package Body:
-------------
Create or Replace Package Body fo_pack
is
Function addval(a number, b number) return Number
is
Begin
return(a+b);
End addval;

Function addval(a number, b number, c number) return number


is
Begin
return(a+b+c);
End addval;

Function addval(str1 varchar2, str2 varchar2) return varchar2


is
Begin
return(str1||str2);
End Addval;

Function addval(str1 varchar2, str2 varchar2, str3 varchar2) return varchar2


is
Begin
return(str1||str2||str3);
End Addval;

End fo_pack;
Select fo_pack.addval(10,20) from dual;

Select fo_pack.addval('Rama ','Krishna ','Raju') from dual;

Select fo_pack.addval(10,20,50) from dual;

-> all packages bodies are stored in 'user_source'.

-> to see the package body.

select text from USER_SOURCE where name='FO_PACK';

Dropping Packages:
-----------------
Drop Package my_pack;

Packages using Dynamic cursors:


------------------------------
Create or Replace Package p1
is
Type Rcur is Ref Cursor;
End p1;

Procedure:
---------
Create or Replace Procedure my_proc(Tdeptno in Emp.Deptno%type,
my_cur out p1.Rcur)
is
Begin
Open my_cur for Select * from emp where Deptno=Tdeptno;
End my_proc;

pl/sql block:
------------
Declare
my_cur p1.Rcur;
e emp%rowtype;
Begin
my_proc(&tdeptno,my_cur);
Loop
fetch my_cur into E;
exit when my_cur%notfound;
dbms_output.put_line(e.empno||' '||e.ename||' '||e.job||' '||e.sal||
' '||e.deptno);
End Loop;
End;
Create a Bank Database with Accno,customer Name, Account type, Opening Date, Balance.

validations:
------------
-> Account no should be generated automatically(ex: sbi1, sbi2,....)
-> Customer name is capital Letters.
-> Opening date is system date
-> account type should be accepts only either 's' or 'c'
-> if account type is savings then Min. Balance is Rs.500/-
-> if account type is current then min. balance is Rs.1000/-.

Create a bank Transaction table with Transaction Account Number, Transaction Date,
Transaction type and Transaction Amount.

Validations:
-----------
-> Taccount Number should be present in Bank Database.
-> Tdate is System date
-> Transaction type should be accepts either 'D' or 'W'
-> Min. Trasaction Amount is Rs.100/-
-> if the customer applying withdraw, check the available balance.
-> if Customer withdrawing or Depositing amount balance should be updated.

Create a Bank Database Table:


-----------------------------
Create Table Bank_Mas(Accno vARCHAR2(5), Cname Varchar2(10),
Odate Date, Acc_type Varchar2(1),
Balance Number(8,2));

Create a Trigger on Bank_Mas:


----------------------------
Create or Replace Trigger Bank_Trig
Before Insert on Bank_Mas
for each row
declare
taccno Number(4);
Begin
select max(substr(accno,4))+1 into taccno from Bank_Mas;
if taccno is null then
:new.accno:='SBI1';
else
:new.accno:='SBI'||Taccno;
end if;
:new.cname:=upper(:new.cname);
:new.Odate:=Sysdate;
if :new.acc_type in('s','S') then
if :new.balance<500 then
raise_application_error(-20001,'Min. Savings A/c. Balance Rs.500/-');
end if;
elsif :new.acc_type in('c','C') then
if :new.balance<1000 then
raise_application_error(-20002,'Min. Current A/c. Balance Rs.1000/-');
end if;
else
raise_application_error(-20003,'Invalid Account Type....');
end if;
End;

Create a Transaction table:


--------------------------
Create table Trans(Taccno Varchar2(5),Tdate Date,
Ttype Varchar2(1), Tamount Number(8,2));

Create a Package:
----------------
Create or replace package bank_pack
is
Function Chk_Bal(Taccno Trans.Taccno%type,
Tamount Trans.Tamount%type) Return Boolean;
Procedure Upd_Bal(Taccno Trans.Taccno%type,
Ttype Trans.Ttype%type,
Tamount Trans.Tamount%type);
End Bank_Pack;

Package Body:
-------------
Create or Replace Package Body Bank_Pack
is
Function Chk_Bal(Taccno Trans.Taccno%type,Tamount Trans.Tamount%type)
Return Boolean
is
Tbal Bank_mas.Balance%type;
Tacc_type Bank_mas.Acc_type%type;
Begin
Select Acc_type,Balance into Tacc_type, Tbal from Bank_mas
where Accno=Taccno;
if Tacc_type in ('s','S') then
if(tbal-Tamount)>=500 then
Return(True);
else
Return(False);
end if;
elsif Tacc_type in ('c','C') then
if(tbal-tamount)>=1000 then
Return(True);
else
Return(False);
End if;
End if;
End chk_bal;

Procedure Upd_Bal(Taccno Trans.Taccno%type,


Ttype Trans.Ttype%type,
Tamount Trans.Tamount%type)
is
Begin
if Ttype in ('d','D') then
update Bank_Mas Set Balance=Balance+Tamount where Accno=Taccno;
elsif Ttype in('w','W') then
update Bank_Mas Set Balance=Balance-Tamount where Accno=Taccno;
End if;
End upd_bal;
End bank_pack;

Create a trigger on Trans:


-------------------------
Create or Replace Trigger Trans_Trig
Before Insert on Trans
for each row
Declare
Cnt number;
Begin
Select count(Accno) into cnt from Bank_mas where Accno=:new.Taccno;
if cnt=0 then
Raise_application_error(-20001,'Invalid Account Number...');
end if;
if :new.Tamount<100 then
Raise_application_error(-20002,'Min. Trans. Amount Rs.100/-');
end if;
:new.tdate:=sysdate;
if :new.ttype in ('w','W') then
if bank_pack.chk_bal(:new.Taccno,:new.Tamount)=True then
Bank_pack.Upd_bal(:new.taccno,:new.ttype,:new.tamount);
else
Raise_application_error(-20003,'Insufficient Balance...');
end if;
elsif :new.ttype in ('d','D') then
Bank_pack.Upd_bal(:new.taccno,:new.ttype,:new.tamount);
else
raise_application_error(-20004,'Invalid Trans. Type....');
end if;
End;
Iteration Control Statements:
-----------------------------
i. Simple Loop
ii. While Loop
iii. for loop
iv. for cursor

i. Simple Loop:
---------------
-> it is an infinite loop.
syntax:
-------
Loop
<exec-statements>;
End Loop;

example:
--------
Begin
Loop
dbms_output.put_line('Welcome');
End Loop;
End;

to break simple loop:


--------------------
syntax1:
--------
if <condition> then
exit;
end if;

example:
-------
Declare
i Number(2):=1;
Begin
Loop
if i<=10 then
dbms_output.put_line('Welcome');
else
exit;
end if;
i:=i+1;
End Loop;
End;
syntax2:
--------
EXIT when <condition>;
example:
-------
Declare
i Number(2):=1;
Begin
Loop
Exit when i>10;
dbms_output.put_line('Welcome');
i:=i+1;
End Loop;
End;

ii. While Loop:


--------------
Syntax:
-------
While <condition>
Loop
<exec-statements>;
<incre/decre>;
End Loop;

Example:
-------
-- write a pl/sql block to print first 10 natural numbers.
Declare
i Number(2):=1;
Begin
while(i<=10)
Loop
dbms_output.put_line(i);
i:=i+1;
End Loop;
End;

-- write a pl/sql block to print multiplication table.


5*1=5
5*2=10
.
.
5*10=50

Declare
N Number(2):=&N;
i Number(2):=1;
Begin
While(i<=10)
Loop
dbms_output.put_line(N||'*'||i||'='||(N*i));
i:=i+1;
End Loop;
End;

-- print 1..10 numbers in reverse order

Declare
i Number(2):=10;
Begin
while(i>=1)
Loop
dbms_output.put_line(i);
i:=i-1;
End Loop;
End;

iii. For Loop:


-------------
-> by default it is incremented by 1.

syntax:
-------
for <index_variable> in <start_value>..<end_value>
Loop
<exec-statements>;
End Loop;

Example:
-------
Begin
for i in 1..10
loop
dbms_output.put_line(i);
end loop;
End;

-- in reverse order

Begin
for i in Reverse 1..10
loop
dbms_output.put_line(i);
end loop;
End;
CURSORS:
--------
Declare
e emp%rowtype;
Begin
select * into e from emp where DEPTNO=&DEPTNO;
dbms_output.put_line(e.empno||' '||e.ename||' '||e.sal||' '||e.deptno);
End;

Cursors:
-------
-> it is one of the private context area.
-> it creates a temporary buffer
-> it is created by using select statement output.
-> it is not stored in db permanently.
-> in pl/sql block whenever select statement returns morethan one record, on that time we are using
cursors concept.

-> basically cursors are two types.


I. Static Cursor
i. Explicit Cursors
ii. Implicit Cursors
II. Dynamic Cursor

I. Static Cursor:
i. Explicit Cursors:
--------------------
-> it is created by User

cursor Operations:
-----------------
i. Declaring the Cursor:
-----------------------
-> in declaration part we can declare the cursor
syntax:
-----
cursor <cursor_name> is <select statement>;

ii. Open <cursor_name>:


----------------------
-> it opens the cursor
-> Memory is allocated, After opened.

iii. Fetch <cursor_name> into <pl/sql variables>:


-------------------------------------------------
-> it fetches data from cursor into pl/sql variables;
-> it fetches one row a time.
iv. Close <cursor_Name>:
-----------------------
-> it closses the cursor
-> allocated memory will be de-allocated.

cursor Attributes:
-----------------
-> it shows status of the cursor
-> it returns boolean value.
syntax:
-------
<cursor_name>%<attribute>;

a. %isopen:
----------
-> it returns true, when the cursor opens successfully.

b. %found:
----------
-> it returns true, when the cursor contains data.

c. %notfound:
-------------
-> it returns true, when the cursor doesn't find any data.

d.%rowcount:
------------
-> it returs number.
-> no.of fetch statements executed.

Example:
--------
Declare
cursor my_cur is select empno,ename,sal,deptno from emp;
tempno emp.empno%type;
tename emp.ename%type;
tsal emp.sal%type;
tdeptno emp.deptno%type;
Begin
Open my_cur;
if my_cur%isopen then
dbms_output.put_line('cursor opens successfully.');
end if;
fetch my_cur into tempno,tename,tsal,tdeptno;
dbms_output.put_line(tempno||' '||tename||' '||tsal||' '||tdeptno);
fetch my_cur into tempno,tename,tsal,tdeptno;
dbms_output.put_line(tempno||' '||tename||' '||tsal||' '||tdeptno);
fetch my_cur into tempno,tename,tsal,tdeptno;
dbms_output.put_line(tempno||' '||tename||' '||tsal||' '||tdeptno);
Close my_cur;
End;

cursors using Simple Loop:


-------------------------
Declare
cursor my_cur is select empno,ename,sal,deptno from emp;
tempno emp.empno%type;
tename emp.ename%type;
tsal emp.sal%type;
tdeptno emp.deptno%type;
Begin
Open my_cur;
if my_cur%isopen then
dbms_output.put_line('cursor opens successfully.');
end if;
Loop
fetch my_cur into tempno,tename,tsal,tdeptno;
Exit when my_cur%notfound;
dbms_output.put_line(tempno||' '||tename||' '||tsal||' '||tdeptno);
End Loop;
Close my_cur;

Open my_cur;
if my_cur%isopen then
dbms_output.put_line('cursor opens successfully.');
end if;
Loop
fetch my_cur into tempno,tename,tsal,tdeptno;
Exit when my_cur%notfound;
dbms_output.put_line(tempno||' '||tename||' '||tsal||' '||tdeptno);
End Loop;
Close my_cur;
End;

cursors using while looP;


------------------------
Declare
cursor my_cur is select empno,ename,sal,deptno from emp;
tempno emp.empno%type;
tename emp.ename%type;
tsal emp.sal%type;
tdeptno emp.deptno%type;
Begin
Open my_cur;
if my_cur%isopen then
dbms_output.put_line('cursor opens successfully.');
end if;
Fetch my_cur into Tempno,Tename,Tsal,Tdeptno;
while(my_cur%found)
Loop
dbms_output.put_line(tempno||' '||tename||' '||tsal||' '||tdeptno);
fetch my_cur into tempno,tename,tsal,tdeptno;
End Loop;
Close my_cur;
End;

--> write a cursor program to print first five max. salaries employee details.
Declare
cursor my_cur is select empno,ename,job,hiredate,sal,deptno from emp order by sal desc;
e my_cur%rowtype;
Begin
Open my_cur;
Loop
Fetch my_cur into e;
Exit when my_cur%rowcount>5;
dbms_output.put_line(e.empno||' '||e.ename||' '||e.sal||' '||e.hiredate||' '||e.deptno);
End Loop;
Close my_cur;
End;

--> write a cursor to displa alternative records.(even or odd records)


Declare
cursor my_cur is select * from emp;
e my_cur%rowtype;
Begin
Open my_cur;
Loop
Fetch my_cur into e;
if (mod(my_cur%rowcount,2)=0) then
dbms_output.put_line(my_cur%rowcount||' '||e.empno||' '||e.ename||' '||e.sal||
' '||e.deptno);
end if;
Exit when my_cur%notfound;
End Loop;
Close my_cur;
End;

cursor with Parameters:


----------------------
-> while opening the cursor to provide parameters is called as cursor with parameters.

Declare
cursor emp_cur(pdeptno number) is select * from emp where deptno=pdeptno;
e emp%rowtype;
Begin
Open emp_cur(10);
Loop
Fetch emp_cur into e;
Exit when emp_cur%notfound;
dbms_output.put_line(emp_cur%rowcount||' '||e.empno||' '||e.ename||' '||e.sal||
' '||e.deptno);
End Loop;
Close emp_cur;
End;

-> max. 32 parameters to pass.

ii. Implicit Cursor:


-------------------
-> it is created by Oracle.
ex: delete from emp where deptno=10;

II. DYNAMIC CURSOR:


------------------
-> to declare the cursor without any select statement.
-> select statement will be provided while opening the cursor.
syntax:
-------
type <cursor_name> is ref cursor;

Static Cursor:
-------------
-> while declaring the cursor to provide select statement is called as Static cursor.

example:
-------

Declare
Type R_cur is Ref Cursor;
my_cur R_cur;
e emp%rowtype;
d dept%rowtype;
Begin
Open my_cur for select * from emp;
Loop
fetch my_cur into e;
dbms_output.put_line(e.empno||' '||e.ename||' '||e.sal||' '||e.hiredate||' '||e.deptno);
Exit when my_cur%notfound;
End Loop;
Close my_cur;
Open my_cur for select * from dept;
Loop
fetch my_cur into d;
dbms_output.put_line(d.deptno||' '||d.dname||' '||d.loc);
Exit when my_cur%notfound;
End Loop;
Close my_cur;
End;

FOR CURSOR:
----------
Declare
cursor emp_cur is select * from emp;
Begin
for i in emp_cur
Loop
dbms_output.put_line(i.empno||' '||i.ename||' '||i.sal||' '||i.hiredate||' '||i.deptno);
End loop;
End;

EXCEPTION HANDLING:
------------------
-> PL/SQL errors are called as Exceptions.
-> Exceptions are classified into 3 types.
I. Pre-Defined Exceptions
II. User-Defined Exceptions
III. Non-Pre-Defined Exceptions

Declare
E Emp%rowtype;
Begin
select * into e from Emp where Empno=&Empno;
dbms_output.put_line(e.empno||' '||e.ename||' '||e.sal||' '||e.deptno);
End;

I. Pre-Defined Exceptions:
-------------------------
-> Exception Name is Defined by Oracle
-> Activated by Oracle
-> Solution is Provided by User

Declare
E Emp%rowtype;
Begin
select * into e from Emp where Empno=&Empno;
dbms_output.put_line(e.empno||' '||e.ename||' '||e.sal||' '||e.deptno);
Exception
when no_data_found then
raise_application_error(-20001,'Such Employee Number Not Exists.');
End;

Example2:
--------
Declare
E Emp%rowtype;
Begin
select * into e from Emp where deptno=&deptno;
dbms_output.put_line(e.empno||' '||e.ename||' '||e.sal||' '||e.deptno);
Exception
when no_data_found then
raise_application_error(-20001,'Such Employee Number Not Exists.');
when too_many_rows then
raise_application_error(-20002,'Morethan One Employee Exists..');
End;

II. User Defined Exceptions:


---------------------------
-> Exception Name is Defined by User
-> Activated by User
-> Solution is Provided by User

example:
--------
Declare
Tsal Emp.Sal%type;
Tcomm Emp.Comm%type;
Netsal Number;
Nulls_Found Exception;
Begin
select Sal,Comm into Tsal,Tcomm From Emp where Empno=&Tempno;
if Tcomm is Null then
Raise Nulls_Found;
end if;
Netsal:=Tsal+Tcomm;
dbms_output.put_line('Salary : '||Tsal);
dbms_output.put_line('Comm : '||Tcomm);
dbms_output.put_line('Net Salary : '||Netsal);
Exception
When Nulls_Found then
Raise_application_error(-20001,'Comm Column value is Null.');
When No_Data_Found then
Raise_application_error(-20002,'Such Employee Number Not Exists');
End;
III. Non-Predefined Exceptions:
------------------------------
-> these exceptions are raised whenever constraint voilated errors occurs.
-> Exception Name is Defined by User
-> Activated by Oracle
-> Solution is provided by User

Declare
Duplicates_Found Exception;
pragma Exception_init(Duplicates_found,-00001);
Begin
Insert into Dept values(&Deptno,'&dname','&loc');
Exception
when Duplicates_found then
raise_application_error(-20001,'Such Department Number is Already Exists.');
End;

Example2:
--------
Declare
Duplicates_Found Exception;
pragma Exception_init(Duplicates_found,-00001);
Nulls_Found Exception;
pragma Exception_init(Nulls_found,-1400);
Begin
Insert into Dept values(&Deptno,'&dname','&loc');
Exception
when Duplicates_found then
raise_application_error(-20001,'Such Department Number is Already Exists.');
when nulls_found then
raise_application_error(-20002,'Department Number is Mandatory...');
End;

composite Datatypes:
-------------------
Composite Datatypes:
? User defined Datatypes
? Created by user in PL/SQL Block
? Valid in PL/SQL only
? They are not stored in database
They are not Re-usable & Shared
? They will not hold data
? They improve performance of Oracle while
Manipulating data in PL/SQL block
2 types
1. PL/SQL Record
2. PL/SQL Table
1. PL/SQL Record
i. It is a collect of elements of different data types and stored at one location
ii. it is similar to C structure
Syntax:
Type <recordname> is record
( Element1 datatype,
Element2 datatype,
..,
ElementN datatype);

example:
---------
Declare
Type Erec is record
(
Empno Number(4),
Name varchar2(10),
Basic Number(7,2),
Job Varchar2(10),
Doj Date,
Deptno Number(2));
e erec;
Begin
e.empno:=&empno;
select Empno,Ename,Sal,Job,Hiredate,Deptno into e.Empno,e.name,E.Basic,e.job,
e.doj,e.deptno from emp where empno=e.empno;
dbms_output.put_line(e.empno||' '||e.Name||' '||e.Job||' '||e.doj||' '||e.deptno);
End;

2.PL/SQL Table

i. It is an collect of elements of same data type


and stored in Continuous
Memory location
ii. it is similar to C arrays

Syntax:

Type <table name> is table of <data type>


index by Binary_integer;

Declare
Type Name is table of Emp.Ename%type index by Binary_Integer;
Type Pay is table of Emp.sal%type index by Binary_Integer;
N Name;
P Pay;
Cnt Number:=0;
Begin
-- filling pl/sql tables
for i in (select ename,sal from emp)
Loop
N(cnt):=i.Ename;
P(cnt):=i.Sal;
cnt:=cnt+1;
End Loop;

-- displaying pl/sql table information.

for k in N.first..N.last
loop
dbms_output.put_line(n(k)||' '||P(k));
end Loop;
End;

TRIGGERS :
Triggers:
? A set of PL/SQL statements stored permanently in database and Automatically activated
when ever an EvenT Raising statement(DML) is performed.
? They are used to impose user defined Restrictions(or)Business Rules on Tables.
? They are also activated when Tables are manipulated by other users or by other application S/w tools.
? They provide High Security on tables
? They are stored in USER_TRIGGERS system table

Trigger Parts:
1. Trigger Event : Indicates when to activate the Trigger
Before
Insert, Update, Delete = 6 Events
After

2. Trigger Type : Indicate the type of Trigger


a. Row Trigger : Trigger is activated for Every Row manipulated by DML statement.

b. Statement Trigger: Trigger is activated only once for 1 DML statement

3. Trigger Restriction :

it Supports to stop the Trigger Execution based on condition

4. Trigger Body :

A set of PL/SQL statements.


Syntax:

Create or Replace Trigger <Trigger_name>


Before/After insert or update OR delete - (1)
[ of <columns> ] on <table name>
[ for each row - (2)
When <condition> (TRUE -> Executes the trigger,
FALSE - Not execute) - (3)
Declare
<variable declaration>; ]
Begin
<exec statements>; - (4)
[ Exception
<exec statements>; ]
End;

sql> insert into dept values(50,'economics','hyd')

:dname='ECONOMICS' :loc='hyd' :depnto=40 -> sql buffer

Create or Replace Trigger Dept_Trig


Before insert on dept
for each row
begin
:new.dname:=upper(:new.dname);
:NEW.LOC:=UPPER(:NEW.LOC);
End;

Write a Trigger program to take employee backup.


Create a backup table with same structure of EMP table.
Create table Backup as select * from emp where 1=2;
If where condition is false it copies Employee table structure only.

Trigger Name: Backup_Trig

Table Name: EMP

Trigger Event: After Delete

Create or Replace Trigger Backup_Trig


After Delete on Emp
for each row
Begin
insert into backup values(:old.empno,:old.ename,:old.job,:old.mgr,
:old.Hiredate,:old.sal,:old.comm,:old.deptno);
End;
SQL> Delete from Emp where Empno=7934;

sql> select * from Emp;

sql> Select * from Backup;

Example:
--------
-> to increment employee salary automatically.

incr:
empno amount
7788 1000

Create a Increment Table:


-------------------------
Create table Incr(Empno Number(4), Amount Number(8,2));

Trigger Name: Incr_Trig

Table Name: Incr

Trigger Event: After Insert

Create or Replace Trigger Incr_Trig


After Insert on Incr
for each row
Begin
Update Emp set sal=sal+:new.Amount where Empno=:new.empno;
End;

Statement Level Triggers:


-------------------------
Create a Holiday table:
-----------------------
Create table Holiday(Hdate Date);

Insert into rows into Holiday table:


-----------------------------------
Insert into Holiday values('&hdate');

Trigger Name: Holi_Trig

Table Name: Emp

Trigger Event: Before insert or update or delete


Create or Replace Trigger Holi_Trig
Before Insert or update or delete
on Emp
Declare
cnt Number;
Begin
if to_char(sysdate,'hh24') not between 10 and 16 then
raise_application_error(-20001,'Offtimings, Trans. are Not allowed.');
End if;

if to_char(sysdate,'dy') in ('sat','sun') then


raise_application_error(-20002,'Weekends, Trans. are Not Allowed.');
end if;

select count(hdate) into cnt from Holiday


where to_char(sysdate,'dd/mm/yy')=to_char(hdate,'dd/mm/yy');
if cnt>0 then
raise_application_error(-20003,'Today Public Holiday, Trans. are Not Allowed.');
End if;
End;

-> Create table Library Database with Book_id, Book_name, Author and Stock.

validations:
------------
-> Book_id should be generated automatically..
-> Book_name is Capital Letters
-> Author name is Initical Capital Letter
-> Min. Stock 1 and Max. Stock 10 should be accepted.

-> Create a Student Database with Sno, sname, Class, Book_id, No.of issued,Issue Date, Return Date.

Validations:
-----------
-> Sname is Capital Letters.
-> Class should be accept only 1 t0 10.
-> Book_id must be present in Library.
-> min. and max. No.of book issue to student only 1.
-> Date of issue is not Grater than System date and Not Less than System date.
-> Date of Return Should Grater than or equal to Date of Issue.
-> if Book is Issuing or returning stock should be updated.

Вам также может понравиться