8/6/2019 unit-3 PL SQL-new
1/112
INTRODUCTION TO PL/ SQL
By :Mrs. Suman Madan
Procedural Language Extension to SQL
8/6/2019 unit-3 PL SQL-new
2/112
PL/SQL Allows using general programming tools with SQL, for example: loops,
conditions, functions, etc.
This allows a lot more freedom than general SQL, and is lighter-weightthan JDBC.
We write PL/SQL code in a regular file, for example PL.sql, and load it
with @PL in the sqlplus console.
Advantages :
Support for SQL
Higher productivity
Better performance Portability
Integration with oracle
8/6/2019 unit-3 PL SQL-new
3/112
Architecture of PL SQL
ORACLE SERVER
PL SQL ENGINE
PL SQL BLOCK
SQL Statement Executor
S
Q
L
PROCEDURAL STATEMENT EXECUTOR
8/6/2019 unit-3 PL SQL-new
4/112
PL SQL CHARACTER SET
Upper and lower case letters
Numerical form
All special symbols and characters
Tab ,space and carriage return
All arithmetic operators
8/6/2019 unit-3 PL SQL-new
5/112
CONTROL STRUCTURES
CONDITIONAL CONTROL
ALL THE BASIC IF CONDITIONS
ITERATIVE CONTROLLOOP ,FOR LOOP ,WHILE LOOP
SEQUENTIAL CONTROLGOTO
8/6/2019 unit-3 PL SQL-new
6/112
PL/SQL Blocks
PL/SQL code is built of Blocks, with a unique structure. There are two types of blocks in PL/SQL:
1. Anonymous Blocks: have no name (like scripts)
can be written and executed immediately in SQLPLUS
can be used in a trigger
2. Named Blocks:
Procedures
Functions
8/6/2019 unit-3 PL SQL-new
7/112
INTRODUCTION TO PLSQL BLOCK
PLSQL BLOCK IS DIVIDED INTO THREE PARTS
DECLARATIVE
EXECUTABLE
EXCEPTION HANDLING
DECLARE
{ DECLARATIONS OF VARIABLES ETC. }
BEGIN
{ EXECUTABLE STATEMENTS }
EXCEPTION
{ HANDLERS }
END;
8/6/2019 unit-3 PL SQL-new
8/112
8/6/2019 unit-3 PL SQL-new
9/112
SAMPLE PROGRAME1Declare
com emp.comm%type;
Begin
select comm into com from emp where empno=7876;
if com is null then
update emp set comm=100 where empno=7876;
else
update emp set comm=200 where empno=7876;end if;
End;
/
8/6/2019 unit-3 PL SQL-new
10/112
Declaring Variables with the
%TYPE Attribute
Examples
DECLARE
sname Sailors.sname%TYPE;fav_boat VARCHAR2(30);my_fav_boat fav_boat%TYPE := 'Pinta';...
Accessing column snamein table Sailors
Accessinganother variable
8/6/2019 unit-3 PL SQL-new
11/112
8/6/2019 unit-3 PL SQL-new
12/112
Declaring Variables with the
%ROWTYPE Attribute
Declare a variable with the type of a ROW of a table.
And how do we access the fields in reserves_record?
reserves_record.sid:=9;
Reserves_record.bid:=877;
reserves_record Reserves%ROWTYPE;
Accessingtable
Reserves
8/6/2019 unit-3 PL SQL-new
13/112
Creating a PL/SQL RecordA record is a type of variable which we can define (like
struct in C or object in Java)DECLARE
TYPE sailor_record_type IS RECORD(sname VARCHAR2(10),
sid VARCHAR2(9),age NUMBER(3),
rating NUMBER(3));
sailor_record sailor_record_type;
...BEGIN
Sailor_record.sname:=peter;Sailor_record.age:=45;
8/6/2019 unit-3 PL SQL-new
14/112
CURSOR MANAGEMENT
A work area called private sql area is used by the
Oracle server to execute SQL statements and
to store processed information.
PLSQL uses cursors to name the private area and
to access the stored information.
8/6/2019 unit-3 PL SQL-new
15/112
Types of CURSORS
There are two types of cursors
EXPLICIT CURSOR
IMPLICIT CURSOR
Syntaxcursor is
8/6/2019 unit-3 PL SQL-new
16/112
Creating a Cursor We create a Cursor when we want to go over a result of
a query
Syntax Example:
DECLAREcursor c is select * from sailors;
sailorData sailors%ROWTYPE;
BEGINopen c;
fetch c into sailorData;
sailorData is a
variable thatcan hold aROW from thesailors table
Here the firstrow of sailorsis inserted intosailorData
8/6/2019 unit-3 PL SQL-new
17/112
Explicit cursor
The set of rows returned by the query can contain zero ormultiple rows depending upon the query defined.
These rows are called the active set.
The cursor will point to the current row in active set.
Once the cursor id defined ,we can use it using the followingcommands to control the cursor.
OPEN - it executes the query
identifies the active set
first row is pointed
Syntax open ;
FETCH - retrieves the current row and the next rows
Syntax fetch into ;
CLOSE - After processing the last row in the active set-cursoris disabled
Syntax Close
8/6/2019 unit-3 PL SQL-new
18/112
Explicit Cursor Attributes
Obtain status information about a cursor.
Attribute Type Description
%ISOPEN Boolean Evaluates to TRUE if the cursoris open.
%NOTFOUND Boolean Evaluates to TRUE if the mostrecent fetch does not return a row.
%FOUND Boolean Evaluates to TRUE if the mostrecent fetch returns a row;complement of %NOTFOUND
%ROWCOUNT Number Evaluates to the total number ofrows returned so far.
8/6/2019 unit-3 PL SQL-new
19/112
The following example illustrates explicit cursors.
Declare
msal emp.sal%type;Cursor c1 is select sal from emp where empno =7876;
begin
Open c1;
loop
fetch c1 into msal;
msal:=msal+msal*0.1;
update emp set sal=msal where empno=7876;
exit when c1 % notfound;
dbms_output.put_line('one row updated');end loop;
close c1;
end;
/
8/6/2019 unit-3 PL SQL-new
20/112
Example 1- %notfoundDeclare
cursor c_emp is select emp_code,salary from employee where deptno=10;
Str_emp_code employee.emp_code%type;
Num_salary employee.salary%type;Begin
open c_emp;
loop
fetch c_emp into str_emp_code, num_salary;
exit when c_emp%notfound;
Update employee set salary=num_salary+(num_salary*0.5)
where emp_code=str_emp_code;
Insert into emp_raise values(str_emp_code,sysdate,num_salary*0.5);
End loop;
Commit;Close c_emp;
End;
/
8/6/2019 unit-3 PL SQL-new
21/112
Example 2- %foundDeclare
cursor c_emp is select emp_code,salary from employee where deptno=10;
Str_emp_code employee.emp_code%type;
Num_salary employee.salary%type;Begin
open c_emp;
loop
fetch c_emp into str_emp_code, num_salary;
if c_emp%found then
Update employee set salary=num_salary+(num_salary*0.5)where emp_code=str_emp_code;
Insert into emp_raise values(str_emp_code,sysdate,num_salary*0.5);
else exit;
end if;
End loop;
Commit;
Close c_emp;
End;
/
E l 3 %i
8/6/2019 unit-3 PL SQL-new
22/112
Example 3- %isopen
Declare
cursor c_emp is select emp_code,salary from employee where deptno=10;
Str_emp_code employee.emp_code%type;
Num_salary employee.salary%type;Begin
open c_emp;
If c_emp%isopen then
loop
fetch c_emp into str_emp_code, num_salary;
Update employee set salary=num_salary+(num_salary*0.5)
where emp_code=str_emp_code;
Insert into emp_raise values(str_emp_code,sysdate,num_salary*0.5);
End loop;
Commit;
Close c_emp;Else dbms_output.put_line(unable to open the cursor);
End if;
End;
/
E l % t
8/6/2019 unit-3 PL SQL-new
23/112
Example - %rowcount
display the names,dname and salary of first 5 employees
Declare
Cursor c_emp is select ename,emp.deptno,sal from emp,dept where
dept.deptno=emp.deptno order by sal desc;n emp.ename%type;
d emp.deptno%type;
s emp.sal%type;
Begin
open c_emp;dbms_output.put_line(name department salary);
dbms_output.put_line(------- ------------- -------);
Loop
fetch c_emp into n,d,s;
dbms_output.put_line(n|| ||d|| ||s);
exit when c_emp%rowcount=5;
End loop;
End;
/
8/6/2019 unit-3 PL SQL-new
24/112
Example - %isopen
Declare
Cursor c4 is select ename,sal from emp where empno=7876;
Begin
If c4%isopen then
Dbms_output.put_line('this message is not displaced');
Else
Open c4;Dbms_output.put_line('cursor opened');
End if;
Close c4;
End;
/
Example with accounts table(accno bal)
8/6/2019 unit-3 PL SQL-new
25/112
Example with accounts table(accno,bal)
Display the first 3 accounts having highest balance
Declare
Cursor c2 is select accno,bal from account order by bal desc;a accounts.accno%type;
b accounts.bal%type;
Begin
Open c2;
Loop
fetch c2 into a,b;
dbms_output.put_line(a|| ||b);
exit when c2%rowcount=3;
End loop;
End;
/
8/6/2019 unit-3 PL SQL-new
26/112
Example
DECLARE
Pi constant NUMBER(8,7) := 3.1415926;
area NUMBER(14,2);
cursor rad_cursor is select * from RAD_VALS;
rad_val rad_cursor%ROWTYPE;
BEGIN
open rad_cursor;
fetch rad_cursor into rad_val;
area:=pi*power(rad_val.radius,2);
insert into AREAS values (rad_val.radius, area);
close rad_cursor;
END;
/
radius
3
6
8
Rad_cursor
fetc
hRad_val
Radius AreaAREAS
3 28.27
RAD_VALS
Rad_cursor
fetc
hRad_val
Radius Area
3 28.27
DECLARE DECLARE
8/6/2019 unit-3 PL SQL-new
27/112
DECLAREcursor rad_cursor is select * from RAD_VALS;rad_val rad_cursor%ROWTYPE;
BEGINopen rad_cursor;fetch rad_cursor into rad_val;
area:=pi*power(rad_val.radius,2);insert into AREAS values (rad_val.radius,area);
DECLARE
cursor rad_cursor is select * fromRAD_VALS;
rad_val RAD_VALS%ROWTYPE;BEGINopen rad_cursor;fetch rad_cursor into rad_val;area:=pi*power(rad_val.radius,2);insert into AREAS values
(rad_val.radius, area);
DECLARE
cursor rad_cursor is select radius from
RAD_VALS;rad_val RAD_VALS.radius%TYPE;
BEGINopen rad_cursor;fetch rad_cursor into rad_val;area:=pi*power(rad_val,2);insert into AREAS values (rad_val, area);
DECLAREcursor rad_cursor is select * from
RAD_VALS;rad_val RAD_VALS.radius%TYPE;
BEGIN
open rad_cursor;fetch rad_cursor into rad_val;area:=pi*power(rad_val,2);insert into AREAS values (rad_val, area);
l
8/6/2019 unit-3 PL SQL-new
28/112
Implicit cursor Implicit cursor attributes can be used to access information about the most
recently executed SQL statement. The most recently executed SQL statement isreffered as SQLCURSOR.
The implicit cursor attributes are :
1. %notfound
2. %found
3. %rowcount
4. %isopen
%NOTFOUND: The %notfound attribute evaluate to true if DML statements donot return any row, else it evaluate to false.
EXAMPLE :
Begin
Delete from customer where name=RAO;
If sql %notfound then
Dbms_output.put_line(value not found);
End if;End;
8/6/2019 unit-3 PL SQL-new
29/112
%FOUND: The %found attribute is the logical opposite of the %notfound attribute.
The %found attribute is evaluates to true if the SQL DML statement affects one ormore rows,else it is evaluated to false.
%ROWCOUNT: The %rowcount attribute counts the number of rows returned by anSQL DML statement .the %rowcount will return zero if the DML statements does
not affect any row.
The following example uses the %rowcount attribute to check if the cursor fetchesany rows.
Declare
Cursor c1 is select name from customer where repid=10;
Cust_rec c1%rowtype;Begin
For cus_rec in c1
Loop
Update customer set name=vivek where repid =10;
If sql%rowcount >0 then Dbms_output.put_line(record exists);End if;
End loop;
End;
8/6/2019 unit-3 PL SQL-new
30/112
SQL Impicit Cursor Attributes
SQL cursor is automatically created after each SQL
query. It has 4 useful attributes:
SQL%ROWCOUNT Number of rows affected by themost recent SQL statement (aninteger value).
SQL%FOUND Boolean attribute that evaluates toTRUE if the most recent SQLstatement affects one or more rows.
SQL%NOTFOUND Boolean attribute that evaluates toTRUE if the most recent SQL
statement does not affect any rows.
SQL%ISOPEN Always evaluates to FALSE becausePL/SQL closes implicit cursorsimmediately after they are executed.
8/6/2019 unit-3 PL SQL-new
31/112
Solution (2)
BEGINupdate mylogset logon_num = logon_num + 1where who = user;
if SQL%ROWCOUNT = 0 theninsert into mylog values(user, 1);
end if;commit;END;
/
The salary of the employees is raised by 20% Write a pl/sql code to accept a empno
8/6/2019 unit-3 PL SQL-new
32/112
The salary of the employees is raised by 20%. Write a pl/sql code to accept a empno
and update the sal and display some message
Begin
Update emp set sal=sal*.02 where empno=&empno;
Ifsql%notfound thenDbms_output.put_line(empno does not exist);
else
Dbms_output.put_line(record modified);
End if;
End;
Begin
Update emp set sal=sal*.02 where empno=&empno;
Ifsql%found thenDbms_output.put_line(record modified);
else
Dbms_output.put_line(empno does not exist);
End if;
End;
OR
8/6/2019 unit-3 PL SQL-new
33/112
The salary of the employees is raised by 20% who are clerks. Write Pl/sql code to
accept empno & update sal and display some message.
Declare
Rows_effected char(4);Begin
Update emp set sal=sal*.02 where job=clerk;
Rows_effected:=to_char(sql%rowcount);
Ifsql%rowcount>0 thenDbms_output.put_line(rows_effected||rows updated);
else
Dbms_output.put_line(no employees as clerks);
End if;End;
%ISOPEN: %isopen is always evaluated to false.
8/6/2019 unit-3 PL SQL-new
34/112
SELECT Statements
INTO clause is required.
Query must return exactly one row.
Otherwise, a NO_DATA_FOUND or TOO_MANY_ROWS exception
is thrown
DECLAREv_sname VARCHAR2(10);
v_rating NUMBER(3);BEGINSELECT sname, ratingINTO v_sname, v_rating
FROM SailorsWHERE sid = '112';END;/
8/6/2019 unit-3 PL SQL-new
35/112
Conditional logic
If
then
elsif then
else
end if;
If
then
if
then
end if;
else
end if;
Condition: Nested conditions:
8/6/2019 unit-3 PL SQL-new
36/112
IF-THEN-ELSIF Statements
. . .IF rating > 7 THENv_message := 'You are great';ELSIF rating >= 5 THENv_message := 'Not bad';ELSEv_message := 'Pretty bad';
END IF;. . .
Suppose we have the following table:
8/6/2019 unit-3 PL SQL-new
37/112
Suppose we have the following table:
Want to keep track of how many
times someone logged on to the
DB
When running, if user is already in
table, increment logon_num.
Otherwise, insert user into table
logon_numwho
3Peter
4John
2Moshe
create table mylog(who varchar2(30),
logon_num number
);
mylog
S l ti
8/6/2019 unit-3 PL SQL-new
38/112
SolutionDECLAREcnt NUMBER;
BEGINselect count(*)into cntfrom mylogwhere who = user;
if cnt > 0 thenupdate mylogset logon_num = logon_num + 1
where who = user;
elseinsert into mylog values(user, 1);end if;commit;
end;
/
L Si l L
8/6/2019 unit-3 PL SQL-new
39/112
Loops: Simple Loop
DECLARE
i number_table.num%TYPE := 1;BEGINLOOPINSERT INTO number_tableVALUES(i);
i := i + 1;EXIT WHEN i > 10;
END LOOP;END;
create table number_table(
num NUMBER(10)
);
L Si l C L
8/6/2019 unit-3 PL SQL-new
40/112
Loops: Simple Cursor Loop
DECLAREcursor c is select * from number_table;
cVal c%ROWTYPE;BEGINopen c;LOOP
fetch c into cVal;EXIT WHEN c%NOTFOUND;insert into doubles values(cVal.num*2);
END LOOP;END;
create table number_table(
num NUMBER(10)
);
Loops: FOR Loop
8/6/2019 unit-3 PL SQL-new
41/112
Loops: FOR Loop
DECLAREi number_table.num%TYPE;
BEGIN
FOR i IN 1..10 LOOPINSERT INTO number_table VALUES(i);
END LOOP;END;
Notice that i is incremented automatically
Loops: For Cursor Loops
8/6/2019 unit-3 PL SQL-new
42/112
Loops: For Cursor Loops
DECLAREcursor c is select * from number_table;
BEGINfor num_row in c loop
insert into doubles_table
values(num_row.num*2);end loop;END;/
Notice that a lot is being done implicitly: declarationof num_row, open cursor, fetch cursor, the exitcondition
Loops: WHILE Loop
8/6/2019 unit-3 PL SQL-new
43/112
Loops: WHILE Loop
DECLARETEN number:=10;i number_table.num%TYPE:=1;
BEGINWHILE i
8/6/2019 unit-3 PL SQL-new
44/112
Printing Output
You need to use a function in the DBMS_OUTPUTpackage in order to print to the output
If you want to see the output on the screen, you must
type the following (before starting):set serveroutput on format wrapped size 1000000
Then print using
dbms_output. put_line(your_string); dbms_output.put(your_string);
8/6/2019 unit-3 PL SQL-new
45/112
Input and output example
set serveroutput on format wrap size 1000000
ACCEPT high PROMPT 'Enter a number: '
DECLARE
i number_table.num%TYPE:=1;
BEGIN
dbms_output.put_line('Look Ma, I can print from PL/SQL!!!');WHILE i
8/6/2019 unit-3 PL SQL-new
46/112
Anonymous Block Structure:DECLARE (optional)
/* Here you declare the variables you will use in this block */
BEGIN (mandatory)/* Here you define the executable statements (what the block
DOES!)*/
EXCEPTION (optional)
/* Here you define the actions that take place if an exception isthrown during the run of this block */
END; (mandatory)
/
Always put a new linewith only a / at the
end of a block! (This
tells Oracle to run the
block)
A correct completion of ablock will generate thefollowing message:
PL/SQL procedure
successfully completed
8/6/2019 unit-3 PL SQL-new
47/112
Concept of error handling
There are 2 types of exceptions.
1.predefined exceptions
2.user-defined exceptions
predefined exception:- predefined exceptionsare raised automatically by the system duringrun time.
user-defined exceptions:- defined by the user
8/6/2019 unit-3 PL SQL-new
48/112
Predefined exception:- predefined exceptions are raisedautomatically by the system during run time.
Syntax for predefined exception is as follows:
Begin
Sequence_of_statements;
ExceptionWhen then
Sequence_of_statements;
When others then /* the last exception in the
exception handler*/Sequence_of_statements;
End;
Trapping Exceptions
8/6/2019 unit-3 PL SQL-new
49/112
Trapping Exceptions
Here we define the actions that should happen
when an exception is thrown. Example Exceptions:
NO_DATA_FOUND
TOO_MANY_ROWS
ZERO_DIVIDE
When handling an exception, consider
performing a rollback When multiple exception is raised, Only one
exception is raised and handled at any time
PREDFINED EXCEPTION
8/6/2019 unit-3 PL SQL-new
50/112
PREDFINED EXCEPTIONNo_data_found : This is raised when select statement returns no
rows.
Cursor_already _open : This is raised when we try to open a cursorwhich is already opened.
Dup_val_on_index :This is raised when we insert duplicate values ina column, which is defined as unique index.
Storage_error : This is raised if PL/SQL runs out of memory.
Program_error : This is raised if PL/SQL has an internal problem.
Zero_error : when we divide a number with zero
Invalid _cursor : This is raised when we violate cursor operation.
Login_denied :This is raised when we try to enter oracle using invaliduser-name/password.
invalid _number :This is raised if the conversion of character string to
a number fails because the string does not represent
a valid number.
Too_many rows : returns more than one row.
Q A t l d di l th l d ti
8/6/2019 unit-3 PL SQL-new
51/112
Q. Accept an employee no and display the sal and an exceptionhandler.
declare
mempno emp.empno%type;
memp emp.sal%type;
begin
select sal into memp from emp where empno=&mempno;
dbms_output.put_line( the salary of that empno is||mempexception
when no_data_found then
dbms_output.put_line('there is no employee withempno);
end;
/
DECLARE
8/6/2019 unit-3 PL SQL-new
52/112
DECLARE
num_row number_table%ROWTYPE;BEGIN
select *into num_row
from number_table;dbms_output.put_line(1/num_row.num);
EXCEPTIONWHENNO_DATA_FOUND THEN
dbms_output.put_line('No data!');WHEN TOO_MANY_ROWS THEN
dbms_output.put_line('Too many!');WHEN OTHERS THEN
dbms_output.put_line(Error);end;
USER DEFINED EXCEPTION:
8/6/2019 unit-3 PL SQL-new
53/112
USER-DEFINED EXCEPTION:-
A user defined exceptions should be declared
and raised explicitly by a raise statement.it canbe declared only in the declarative part of thePL/SQL block.
SYNTAX:
exception;
SYNTAX FOR RAISE STATEMENT:
Raise ;
User-Defined Exception
8/6/2019 unit-3 PL SQL-new
54/112
User-Defined ExceptionDECLARE
e_number1 EXCEPTION;
cnt NUMBER;BEGINselect count(*)into cntfrom number_table;
IF cnt = 1 THEN RAISE e_number1;ELSE dbms_output.put_line(cnt);END IF;
EXCEPTIONWHEN e_number1 THEN
dbms_output.put_line('Count = 1');
end;
declaremempno emp empno%type;
Example User
8/6/2019 unit-3 PL SQL-new
55/112
mempno emp.empno%type;msal emp.sal%type;mcom emp.comm%type;
myexec exception;
mynextexec exception;begin
select sal,comm into msal,mcom from emp whereempno=&mempno;
dbms_output.put_line( the salary of that empno is||msal);If msal2000 then raise mynextexec;end if;
exceptionWhen myexec then
dbms_output.put_line(sal is less than 1000);
When mynextexec thendbms_output.put_line(sal is more than 2000);
when no_data_found thendbms_output.put_line('there is no employee with empno);
end;
/
Defined Exception
8/6/2019 unit-3 PL SQL-new
56/112
Functions and Procedures
Up until now, our code was in an anonymousblock
It was run immediately
It is useful to put code in a function or
procedure so it can be called several times
Once we create a procedure or function in a
Database, it will remain until deleted (like a
Creating Procedures
8/6/2019 unit-3 PL SQL-new
57/112
CREATE [OR REPLACE] PROCEDURE
procedure_name[(parameter1 [mode1] datatype1,parameter2[mode2] datatype2,. . .)]
IS|ASPL/SQL Block;
Creating Procedures
Modes:
IN: procedure must be called with a value for the parameter. Value cannotbe changed
OUT: procedure must be called with a variable for the parameter. Changesto the parameter are seen by the user (i.e., call by reference)
IN OUT: value can be sent, and changes to the parameter are seen by theuser
Default Mode is: IN
Example- what does this do?
8/6/2019 unit-3 PL SQL-new
58/112
create or replace procedurenum_logged(person IN mylog.who%TYPE,
num OUT mylog.logon_num%TYPE)ISBEGIN
select logon_num
into numfrom mylogwhere who = person;
END;/
Example what does this do?
logon_
numwho
3Pete
4John
2Joe
Table mylog
Calling the Procedure
8/6/2019 unit-3 PL SQL-new
59/112
declarehowmany mylog.logon_num%TYPE;
beginnum_logged(John',howmany);dbms_output.put_line(howmany);
end;/
Calling the Procedure
Errors in a Proced re
8/6/2019 unit-3 PL SQL-new
60/112
Errors in a Procedure
When creating the procedure, if there are errors in itsdefinition, they will not be shown
To see the errors of a procedure called myProcedure,
typeSHOW ERRORS PROCEDURE myProcedure
in the SQLPLUS prompt
For functions, typeSHOW ERRORS FUNCTION myFunction
Creating a Function
8/6/2019 unit-3 PL SQL-new
61/112
Creating a Function
Almost exactly like creating a procedure, but
you supply a return type
CREATE [OR REPLACE] FUNCTIONfunction_name
[(parameter1 [mode1] datatype1,parameter2[mode2] datatype2,. . .)]
RETURN datatypeIS|ASPL/SQL Block;
8/6/2019 unit-3 PL SQL-new
62/112
create or replace functionrating_message(rating IN NUMBER)return VARCHAR2
ASBEGIN
IF rating > 7 THENreturn 'You are great';
ELSIF rating >= 5 THENreturn 'Not bad';
ELSEreturn 'Pretty bad';END IF;
END;/
A Function
NOTE THAT YOU
DON'T SPECIFY THE
SIZE
C lli th f ti
8/6/2019 unit-3 PL SQL-new
63/112
declarepaulRate:=9;
Begindbms_output.put_line(ratingMessage(paulRate));end;/
Calling the function
Creating a function:
8/6/2019 unit-3 PL SQL-new
64/112
create or replace function squareFunc(num in number)
return number
isBEGIN
return num*num;
End;
/
BEGIN
dbms_output.put_line(squareFunc(3.5));
END;
/
Creating a function:
Using the function:
DATABASE TRIGGERS
8/6/2019 unit-3 PL SQL-new
65/112
DATABASE TRIGGERS A database trigger is a stored procedure that is fired when an
insert, update or delete statement is issued against the
associated table.
Database triggers can be used for the following purposes.
To generate data automatically.
To enforce complex integrity constraints.
To customize complex security authorizations.
To maintain replicate tables.
To audit data modifications.
SYNTAX: Create or replace trigger
8/6/2019 unit-3 PL SQL-new
66/112
SYNTAX: Create or replace trigger
[before/after]
[insert/update/delete] on
[for each statement/for each row]
[when ];
PARTS OF TRIGGER: THERE ARE 3 PARTS OF TRIGGER:
1.TRIGGER STATEMENTS: The trigger statement specifies the DML
statement like update,delete and insert and it fires the trigger body. It
also specifies the table to which the trigger is associated.
2.TRIGGER BODY: It is PL/SQL block that is executed when a
triggering statement is issued.
3.TRIGGER RESTRICTION: Restrictions on a trigger can be achieved
using the WHEN clause.WHEN clause is evaluated for each row that
is affected by the trigger.
EXAMPLE 1:
8/6/2019 unit-3 PL SQL-new
67/112
EXAMPLE 1:Create or replace trigger trig
Before insert
On emp
For each row
Declare
eno emp.empno%type;Begin
Select empno into eno from emp where deptno=10;
If eno =1000 then
Raise_application_error(-20001,enter some other number);End if;
End;
EXAMPLE 2:
8/6/2019 unit-3 PL SQL-new
68/112
Create or replace trigger sun_trig
Before insert or update or delete
On emp
Declare
enter_date char;
Begin
enter_date := to_char(sysdate ,dy);
If enter_date in(sat,sun) then
Raise_application_error(-20001,try on any
weekdays);End if;
End;
application error_numbers is20000 to -20999
Message is character string up to 2048 bytes of length
ENABLING AND DISABLING TRIGGERS:
8/6/2019 unit-3 PL SQL-new
69/112
A triggers can be enabled or disabled. An enabled trigger executesthe trigger body if the triggering statements is issued. By default,triggers are enabled. Disabled trigger does not execute the trigger
body even if the triggering statements is issued.
SYNTAX:
Alter trigger disable;
DROPPING TRIGGER:
To drop a trigger from the database, the drop trigger command isused.
SYNTAX:
Drop trigger;
>Alter table emp
Disable all triggers;
8/6/2019 unit-3 PL SQL-new
70/112
EXAMPLES
Example Programs - LOOP
8/6/2019 unit-3 PL SQL-new
71/112
p g
declare
a number : = 100;
begin
loop
a := a + 25 ;exit when a=250;
dbms_output.put_line(a);
end loop;
end;
/
Example Programs - WHILE
8/6/2019 unit-3 PL SQL-new
72/112
p g
declare
i number:=0;
j number := 0;
begin
while i
8/6/2019 unit-3 PL SQL-new
73/112
p g
declare
a emp.empno%type;b emp.sal%type;
begin
for i in 1..5
loopupdate emp set sal=1000 where empno=7876;
select empno,sal into a,b from emp where empno=7876;
dbms_output.put_line(a);
dbms_output.put_line(b);
end loop;
end;
/
Example Programs - FOR
8/6/2019 unit-3 PL SQL-new
74/112
p g
declare
amt number(10,2);i number;
begin
amt:=2000;
for i in 1..5 loop
amt:=amt+100;
dbms_output.put_line(amt);
end loop;end;
/
EXAMPLE - FOR %FOUND&%ROWCOUNT
8/6/2019 unit-3 PL SQL-new
75/112
declare
Cursor c2 is select empno,ename,sal,comm from emp where deptno=10;
s emp.sal%type;
c emp.comm%type;e emp.empno%type;
n emp.ename%type;
Begin
Open c2;
LoopFetch c2 into e,n,s,c;
If c2%found then
Dbms_output.put_line('fetches more than two rows');
Dbms_output.put_line(e||n||s||c);
else
Exit when c2%rowcount>2;
End if;
End loop;
Close c2;
End;
/
EXAMPLE : pl/sql code for cursor for loop
8/6/2019 unit-3 PL SQL-new
76/112
Declare
Cursor for_cus is select name from customer where city=hyd;
a for_cus%rowtype;
Begin
For cust_rec in fro_cur loop
Delete from customer where name=readymoney;
Commit;
End loop;
Dbms_output.put_line(name has been deleted);
End;
Example :Check for the employee called rao and delete the record
8/6/2019 unit-3 PL SQL-new
77/112
Declare
Cursor for_emp is select ename from emp ;
a for_emp%rowtype;
Begin
For cust_rec in for_emp
loop
exit when for_emp%notfound;
Delete from emp where ename='rao' ;Commit;
End loop;
Dbms_output.put_line('name has been deleted');
End;/
DECLARE
CURSOR c1 is
8/6/2019 unit-3 PL SQL-new
78/112
CURSOR c1 is
SELECT ename, empno, sal FROM emp
ORDER BY sal DESC; -- start with highest-paid employee
my_ename CHAR(10);
my_empno NUMBER(4);my_sal NUMBER(7,2);
BEGIN
OPEN c1;
FOR i IN 1..5 LOOPFETCH c1 INTO my_ename, my_empno, my_sal;
EXIT WHEN c1%NOTFOUND;
/* in case the number requested is more than the total number of employees*/
INSERT INTO temp VALUES (my_sal, my_empno, my_ename);
COMMIT;END LOOP;
CLOSE c1;
END;
/
DECLARE
8/6/2019 unit-3 PL SQL-new
79/112
acct_balance NUMBER(11,2);
acct CONSTANT NUMBER(4) := 3;
debit_amt CONSTANT NUMBER(5,2) := 500.00;
BEGIN
SELECT bal INTO acct_balance FROM accounts
WHERE account_id = acct FOR UPDATE OF bal;
IF acct_balance >= debit_amt THEN
UPDATE accounts SET bal = bal - debit_amt WHERE account_id = acct;
ELSE
INSERT INTO temp VALUES (acct, acct_balance, 'Insufficient funds');
-- insert account, current balance, and message
END IF;COMMIT;
END;
/
DECLAREsalary emp.sal%TYPE;
8/6/2019 unit-3 PL SQL-new
80/112
mgr_num emp.mgr%TYPE;
last_name emp.ename%TYPE;
starting_empno CONSTANT NUMBER(4) := 7902;
BEGIN
SELECT sal, mgr INTO salary, mgr_num FROM emp
WHERE empno = starting_empno;
WHILE salary < 4000 LOOP
SELECT sal, mgr, ename INTO salary, mgr_num, last_name
FROM emp
WHERE empno = mgr_num;
END LOOP;
INSERT INTO temp VALUES (NULL, salary, last_name);COMMIT;
END;
/
use of %ROWTYPE is allowed. (Column names in a cursor declaration
8/6/2019 unit-3 PL SQL-new
81/112
** must have aliases if they are not simple names.)
DECLARE
CURSOR my_cursor IS SELECT sal + NVL(comm, 0) wages, ename FROM emp;
my_rec my_cursor%ROWTYPE;
BEGIN
OPEN my_cursor;
LOOP
FETCH my_cursor INTO my_rec;
EXIT WHEN my_cursor%NOTFOUND;
IF my_rec.wages > 2000 THEN
INSERT INTO temp VALUES (NULL, my_rec.wages, my_rec.ename);
END IF;
END LOOP;
CLOSE my_cursor;
END;
This block calculates the total wages (salary plus commission) paid to employees in department20. It also determines how many of the employees have salaries higher than $2000, and how
h i i l th th i l i
8/6/2019 unit-3 PL SQL-new
82/112
many have commissions larger than their salaries.
DECLARE
CURSOR emp_cursor(dnum NUMBER) IS
SELECT sal, comm FROM emp WHERE deptno = dnum;
total_wages NUMBER(11,2) := 0;
high_paid NUMBER(4) := 0;
higher_comm NUMBER(4) := 0;
BEGIN
/* The number of iterations will equal the number of rows returned by emp_cursor */
FOR emp_record IN emp_cursor(20)
LOOPemp_record.comm := NVL(emp_record.comm, 0);
total_wages := total_wages + emp_record.sal + emp_record.comm;
IF emp_record.sal > 2000.00 THEN
8/6/2019 unit-3 PL SQL-new
83/112
high_paid := high_paid + 1;
END IF;
IF emp_record.comm > emp_record.sal THEN
higher_comm := higher_comm + 1;
END IF;
END LOOP;
INSERT INTO temp VALUES (high_paid, higher_comm,
'Total Wages: ' || TO_CHAR(total_wages));
COMMIT;
END;
/
Write a pl/sql code to accept account number and print the name and balance ofaccount holder.
8/6/2019 unit-3 PL SQL-new
84/112
Tablename:bank
ACCNO NAME BAL
101 Renuka 5000102 madhu 2000
Declare
a number(3);
b number(7,2);
m varchar(10);
BeginSelect name,bal into m,b from bank where accno=&a;
Dbms_output.put_line(m||b);
End;
PROGRAM2: Write a pl/sql code accept accno, ttype and amount asinputs from the user to update balance and to print everything.
8/6/2019 unit-3 PL SQL-new
85/112
p p p y g
TABLENAME:BANK
ACCNO NAME BAL
101 renu 6000102 satya 6000
103 madhu 7000
Declare
a bank.accno%type;
n bank.name%type;
b bank.bal%type;
ttype varchar(1);
amt number(7,2);begin
a:=&a ;
select name,bal into n,b from bank where accno=a;
ttype:=&ttype;
t t
8/6/2019 unit-3 PL SQL-new
86/112
amt:=amt;
if ttype=c then
update bank set bal=b+amt where accno=a;
elsif
ttype=d then
update bank set bal=b-amt where accno=a;
else
dbms_output.put_line(invalid transaction);
end if;
dbms_output.put_line(a|| ||n||||b);
end;
PROGRAM NO 3Write a pl/sql code to take a customer number as input
d d hi d i h 5% i
8/6/2019 unit-3 PL SQL-new
87/112
and update his due amount with 5% interest
TABLE NAME:CUSTOMER
CODE NAME DAMT
1 Anu 5000
2 Aryani 1000
3 Madhu 900
Declare
c customer.code%type;
n customer.name%type;d customer.damt%type;
Begin
C:=&c;Select name,damt into m,d from customer where code=c;
Update customer set damt=damt+dmt*0.05 where code=c;
Dbms_output.put_line(c|| ||m|| ||d);
End;
PROGRAM NO:4Write a PL/SQL code to accept code as input from the user,check for the due amt.if the
d i d l h d f h bl
8/6/2019 unit-3 PL SQL-new
88/112
due amount is zero delete the record from the table.
TABLENAME:CUST
CODE NAME DAMT
101 A 700
102 B 700103 C 800
Declare
a cust.code%type;
b cust.damt%type;
Begina:=&a;
select damt into b from cust where code=a ;
if b=0 then
delete from cust where code=a;else
dbms_output.put_line(damt is not zero);
end if;
end;
PROGRAM NO.5Write a PL/SQL code to accept a customer code as input check for the due amount,if thedue amount is zero delete the record from the table use procedure for the above
8/6/2019 unit-3 PL SQL-new
89/112
due amount is zero,delete the record from the table.use procedure for the aboveprogrram.
TABLE NAME:CUSTOMER
CODE NAME DAMT101 divya 580102 eistein 790103 fathima 0
Declarec customer.code%type;
m customer.name%type;d customer.damt%type;
Beginc:=&c;
Select damt ,name into d,m from customer where code=c;If d=0 then Goto dele;ElseDbms_output.put_line(damt is not zero);Endif;
delete from customer where code=c;
end;
PROGRAM NO.6 Write a PL/SQL code to accept a student no. and give them a graceof 10 marks,if his total is in between 250 and 255.
8/6/2019 unit-3 PL SQL-new
90/112
TABLE NAME:STUDENT
SNO NAME TOT
101 Anu 250
102 ARYU 245
103 CLINTON 255
Declare
r student.sno%type;
m student.name%type;
t student.tot%type;begin
r:=&r;
select name,tot into m,t from student where rno=r;
if t>=250 and t
8/6/2019 unit-3 PL SQL-new
91/112
every student who secured total marks between 250 & 255TABLENAME: student
RNO NAME TOTAL
101 a 260
102 b 245103 c 279
Declare
r stud.r no%type;
n stud.name%typet stud.total%type;
begin
update student set total=total+10 where
total>=250 and total>=255;end;
PROGRAM 8 Write a pl/sql code to read a record from a
8/6/2019 unit-3 PL SQL-new
92/112
OG 8 W te a p /sq code to ead a eco d o a
table and store the rows in the second tableTABLENAME: student
RNO NAME TOTAL
101 a 260
102 b 245
103 c 279
TABLENAME:TEMP
RNO NAME TOTAL
Declarer student.rno %type;
n student.name%type;
t student.total%type;
beginr:=&r;
select name, total into n,t from student where rno=r;
insert into temp values(r,n,t);
end;
PROGRAM NO9 : Create a student table with rno and name.Create a marks table with rno marks and total
8/6/2019 unit-3 PL SQL-new
93/112
Create a marks table with rno,marks and total.Write a pl/sql code to accept rno and display name,marks and total.TABLENAME:student
RNO NAMETABLENAME:MARKSRNO M1 M2 M3 TOTAL101 40 50 35 125
Declarer student.rno%type;
n student.name%type;a marks.m1%type;b marks.m2%type;c marks.m3%type;t marks.total%type;
beginr:=&r;select name,m1,m2,m3,total into n,a,b,c,t from student,marks
where student.rno=r and marks.rno=r;dbms_output_put_line(n||||a||||b||||c||||t);
end;
PROGRAM10Write pl/sql code to calculate interest on due amount for a
8/6/2019 unit-3 PL SQL-new
94/112
Write pl/sql code to calculate interest on due amount for a
particular candidate and add the amount to dueamount for
that customer interest is calculated.
Damt interest
>=10000 5%
>=5000 2.5%
>=2500 1.25%else 0.25%
TABLENAME CUSTOMER
CODE NAME DAMT
101 a 1000102 b 4000
103 c 6000
104 d 7000
Declare
8/6/2019 unit-3 PL SQL-new
95/112
c customer.code%type; d customer.damt%type;
begin
c:=&c;select damt into d from customer where code=c;
if d>=10000 then
update customer set damt=d+a*5/100 where code=c;
elsif d>=5000 then
update customer set damt=d+a*2.5/100 where code=c;
elsif d>=2500 then
update customer set damt=d+a*1.25/100 where code=c;else
update customer set damt=d+a*0.25/100 where code=c;]
end if;
end;
PROGRAM 11Write a pl/sql code using pre defined exception
8/6/2019 unit-3 PL SQL-new
96/112
Write a pl/sql code using pre-defined exception
to accept accno as input from the user and
display bal on the screen. Raise two exceptionwhen data not found and too many rows.
TABLENAME BANKACCNO NAME BAL
101 A 600
102 B 700
103 C 800
104 D 600
Declare
a bank accno%type;
8/6/2019 unit-3 PL SQL-new
97/112
a bank.accno%type;
b bank.bal%type;
n bank.name%type;begin
a:=&a;
select name, bal into n,b from bank where accno=a;
dbms_output.put_line(n||||b);Exception
When no_data_found then
Dbms_output.put_line(record not found);
When too_many_rows thenDbms_output.put_line(too many rows);
End;
PROGRAM 12
8/6/2019 unit-3 PL SQL-new
98/112
Write a pl/sql code using user defined exceptionto accept accno as input from the user andprint the bal on the screenRaise an exception if bal is zero or bal is null;
TABLE NAME BANK
ACCNO NAME BAL
101 A 0
102 B 2000103 C 4000104 D
Declarea bank.accno%type;
8/6/2019 unit-3 PL SQL-new
99/112
a bank.accno%type;b bank.bal%type;n bank.name%type;
begina:=&a;
select name,bal into b,n from bank where accno=a;if b==0 or b is null then
raise e;else
dbms_output.put_line(n||||b);end if;
exceptionwhen e then
dbms_output.put_line(no bal exist);end;
PROGRAM 13Write a pl/sql code to accept accno and amt as input
8/6/2019 unit-3 PL SQL-new
100/112
W te a p /sq code to accept acc o a d a t as put
from the user. If ttype=c update bal with amount. If
ttype=d update bal=bal-amt. Raise an exception ifttype as null;
TABLE NAME BANK
ACCNO NAME BAL TTYPE
101 A 4000 D
102 B 5000 C103 C 5000 NULL
Declaret bank.ttype%type; a bank.accno%type;
8/6/2019 unit-3 PL SQL-new
101/112
b bank.bal%type; n bank.name%type;
amt number(7,2); e exception;
begina:=&a;
amt:=&amt;
select name,bal,ttype into n,b,t from bank where accno=a;
if t=c then update bank set bal=bal+amt whereaccno=a;
elsif t=d then update bank set bal=bal-amt where
accno=a;
elsif t=null then raise e;end if;
exception
when e then dbms_output.put_line(ttype is null);
end;
PROGRAM 14
8/6/2019 unit-3 PL SQL-new
102/112
Write a pl/sql code to explain the use ofpredefined exception
TABLENAME BANK
ACCNO NAME BAL
201 A 5000202 B 6000
203 C 7000
Declare
m bank accno%t pe;
8/6/2019 unit-3 PL SQL-new
103/112
m bank.accno%type;
b bank.bal%type;
begin
m:=&m;
select bal into b from bank where accno=m;
dbms_output.put_line(b);
exception
when no_data_found then
dbms_output.put_line(not found);
end; PROGRAM 15
Write a pl/sql code to explain the use of predefined exceptions
8/6/2019 unit-3 PL SQL-new
104/112
TABLENAME BANK
ACCNO NAME BAL
101 A 5000102 B 6000
103 D 5000
104 E 1000
PROGRAM
m bank.accno%type;
b bank.bal%type;begin
m:=&m;
select bal into b from bank where accno=m;
dbms_output.put_line(b);
exception
when no_data_found then
dbms_output.put_line(not found);
end;
OUTPUT
SQL>sta p5
Enter value for m:204
Not found
PROGRAM 16Write a pl/sql code to fire a trigger before deletion. The user should not be allowed to
delete the record if bal=1000
8/6/2019 unit-3 PL SQL-new
105/112
delete the record if bal=1000
TABLE NAME BANK
ACCNO NAME BAL
100 A 2000101 B 5000
102 V 1000
PROGRAM
Create or replace trigger trig4 before delete on bankDeclare
b bank.bl%type;
begin
select bal into b from bank where accno=101;
if b=1000 then raise_application_error(-2000,DELETION NOT POSIBLE);
end if;
end;
OUTPUT
SQL>sta renu
Tri er created
PROGRAM 17
Write a pl/sql code to fire a trigger before insertion. The user
8/6/2019 unit-3 PL SQL-new
106/112
W te a p /sq code to e a t gge be o e se t o . e use
should not be allowed to insert any record on Wednesday.
PROGRAMCreate or replace trigger trig1 before insert on bank
Declare
S varchar(3);Begin
S:=to_char(sysdate,dd);
If s=wed then
Raise_application_error(-20020,insertion is not possible on wed);End if;
End;
PROGRAM 18 Write a pl/sql code to update balance with 30% interest using cursors.TABLENAME BANK
ACCNO NAME BAL
8/6/2019 unit-3 PL SQL-new
107/112
100 A 2000
101 B 4000
102 CV 6000
Declare
b bank.bal%type;
n bank.name%type;
a bank.accno%type;
cursor c1 is select bal from bank where accno=101;
begin
open c1;
loop
fetch c1 into b;
exit when c1% notfound;
if c1% found then
update bank set bal=b*30/100 +b where accno=101;dbms_output.put_line(record update);
end if;
end loop;
close c1;
end;
PROGRAM 19Write a pl/sql code to display record using cursors and display appropriate message for records found and not
found
8/6/2019 unit-3 PL SQL-new
108/112
TABLENAME BANK
ACCNO NAME BAL
100 A 2000
101 B 4000102 CV 6000
Declare
b bank.bal%type;
n bank.name%type;
a bank.accno%type;
cursor c1 is select bal from bank where accno=101;begin
open c1;
loop;
fetch c1 into b;
exit when c1%notfound;if c1%found then
dbms_output.put_line(record found);
end if;
end loop;
close c1;
PROGRAM 20 Write a pl/sql code with cursors to updatedamt with 5% interest and display message if not found
8/6/2019 unit-3 PL SQL-new
109/112
TABLENAME CUSTOMER
CODE NAME DAMT100 A 500101 B 600102 C 700103 D 500
Declared customer.damt%type;c customer.code%type;
n customer.name%type;cusor c3 is select damt,name from customer where code=100;
beginopen c3;
loopfetch c3 into d,n;
exit when c3% not found;update customer set damt = damt * 5/100 + damt where
code100;dbms_output.put_line(d||||n);end loop;
close c3;
end;
PROGRAM 21Write a pl/sql code with implicit cursors to accept the accno and amount from the user and update the table.Display appropriate messages for found and not found. Display the updated bal on the screen.
TABLENAME BANK
8/6/2019 unit-3 PL SQL-new
110/112
TABLENAME BANK
ACCNO NAME BAL
100 A 2000
101 B 4000
102 CV 6000
Declare
a number(5);
b number(7,2);
amt number(7,2);
beginamt:=&amt;
a:=&a;
update bank set bal=bal+amt where accno=a;
if sql%notfound then
dbms_ouput.put_line(not found);
else
select bal into b from bank where accno=a;
dbms_output.put_line(record found||b);
end if;
end;
1. Display employee names, department number and department names for all
Practice Sheet - JOINS
8/6/2019 unit-3 PL SQL-new
111/112
p y p y p p
departments including the department in which no employee is currently
working.
2. Display all rows in the EMP table, which is the left table even if there is nomatch in the DEPT table. (left outer join)
3. Display all rows in the DEPT table, which is the right table even if there is no
match in the EMP table. (right outer join)
4. Display all rows in the EMP table, even if there is no match in the DEPT table.
It also retrieves all rows in the DEPT table, even if there is no match in the
EMP table.
5. Display the employee last name and employee number along with their
managers last name and manager number. (self join)
6. Display all employees including King, who has no manager. Order the results
by the employee number.
7. Create a query that displays employee last names, department numbers, and allthe employees who work in the same department as a given employee. Give
each column an appropriate label.
1. Create a PL/SQL block that selects the maximum department no fro DEPT
Practice Sheet PL/SQL/Cursor/Triggers/Procedure
8/6/2019 unit-3 PL SQL-new
112/112
p
table and store it in a variable. Print the output on the screen.
2. Create a PL/SQL block that computes the commission amount for a given
employee based on the employee salary. Accept the employee number as userinput. If sal =1000 and sal 1500 then comm = 20% of sal. Update the
emp table with new commission amount for the employee.
3. Write a pl/sql code to display record of employees 1000 and 1001 using
cursors and display appropriate message for record found and not found.
4. Write a pl/sql code to fire a trigger before insertion of a record in EMP table.
The user should not be allowed to insert any record on Wednesday.
5. Write a pl/sql code to fire a trigger before deletion of a record from EMP table.
The user should not be allowed to delete the record if salary=1000
6. Write a PL/SQL procedure that accepts the salary of employee from the user
and add Rs. 2000 /- to the salary of all employees having salary less than theentered salary.