ORACLE 4PM PLSQL
ORACLE 4PM PLSQL
ORACLE
DATABASE
SQL TABLES
PL/SQL ROWS & COLUMNS
SQL:
• SQL is Non-Procedural Language
• just we write queries. we will not programs [set of statements]
PL/SQL:
• PL => Procedural Language
• SQL => Structured Query Language
Advantages of PL/SQL:
ORACLE SERVER
Client
request
INSERT
response
DELETE
UPDATE
request
PL/SQL program
INSERT
response
DELETE
UPDATE
Example:
increase salary
after increment if salary is more than 50000 => ROLLBACK
otherwise => COMMIT
Ex:
Update salary to all emps with different hikes
Modularity:
• Modularity is a programming style.
Procedure-1
Procedure-2
.
.
Procedure-3
Advantages:
• improves understandability
• provides reusability
• reduces length of code
better maintenance
ORACLE 4PM PLSQL Page 3
• better maintenance
Exception Handling:
Exception Handling:
The way of handling run-time error is called Exception Handling.
100 lines
…..
…….
… 50th line => Run-Time Error
…..
…… Application will be closed
Provides Security:
Types of Blocks:
2 Types:
Anonymous Block
ORACLE 4PM PLSQL Page 4
• Anonymous Block
• Named Block
Anonymous Block:
A block without name is called "Anonymous Block".
Named Block:
A block with the name is called "Named Block"
Exs:
Procedures, Functions, Triggers, Packages
DECLARE
--declare the variables declaration part [optional]
BEGIN
--executable statements
execution part
END;
/
DATA TYPES
DECLARE
ASSIGN
INITIALIZE
PRINT
dbms_output.put_line('hello');
In C:
printf("hello");
In Java:
System.out.println("hello");
PACKAGE dbms_output
Ex:
dbms_output.put_line('HELLO');
put_line():
• It is a packaged procedure.
• It is defined in "DBS_OUTPUT" package.
• It is used to print the data.
BEGIN
dbms_output.put_line('HELLO');
END;
/
• Login as USER.
○ username: c##batch4pm
○ password: nareshit
Syntax: @<path_of_sqlfile>
SERVEROUTPUT:
• It is a parameter.
• Its default value is: OFF
• If it is OFF, messages cannot be sent to output.
• To send messages to output, it must be ON.
nChar(n)
nVarchar2(n)
nCLOB
Variable:
• It is an Identifier.
• It is a name of storage location.
• It holds a value.
• It can hold one value only.
Declaring Variable:
Syntax:
<variable> <data_type>;
Exs:
x INT;
s STRING(10);
a NUMBER(4);
b VARCHAR2(10);
c DATE;
Assigning Value:
x=25;
Syntax:
<variable> := <constant / variable / expression>;
= Assignment Operator
Exs: x y z
x := 25; --25 - constant 25 25 50
y := x; --x - variable
z := x+y; -- x+y - expression
x+y := z; //INVALID
25 := z; //INVALID
ORACLE 4PM PLSQL Page 9
25 := z; //INVALID
Initializing value:
Examples: x
x
null
25
x INT; --declare 25
x INT := 25;
x := 25; --assign
Printing data:
dbms_output.put_line(x);
Reading data:
x := &x;
Output:
enter value for x: 25
old: &x
new: 25
x := &x
x := 25
DECLARE x INT;
ASSIGN x := 25;
INITIALIZE x INT := 25;
PRINT dbms_output.put_line(x);
READ x := &x;
print result
x y z
DECLARE
x INT; 20 30 50
y INT;
z INT;
BEGIN
x := 20;
y := 30;
z := x+y;
dbms_output.put_line('sum=' || z);
dbms_output.put_line('sum of ' || x || ' and ' || y || ' is ' || z);
END;
/
Output:
sum=50
sum of 20 and 30 is 50
DECLARE
x INT;
y INT;
z INT;
BEGIN
x := &x;
y := &y;
z := x+y;
dbms_output.put_line('sum=' || z);
dbms_output.put_line('sum of ' || x || ' and ' || y || ' is ' || z);
END;
/
SQL> @d:\ora4pm\ReadDemo.sql
Enter value for x: 5
old 6: x := &x;
new 6: x := 5;
Enter value for y: 4
old 7: y := &y;
new 7: y := 4;
sum=9
sum of 5 and 4 is 9
VERIFY:
• it is a parameter
• its default value is ON
• set it as OFF to avoid OLD and NEW parameters
SQL> @d:\ora4pm\ReadDemo.sql
Enter value for x: 10
Enter value for y: 5
sum=15
sum of 10 and 5 is 15
Example: x y
SELECT ename, sal INTO x, y SMITH 800
FROM emp
WHERE empno=7369;
EMP
EMPNO ENAME SAL HIREDATE
7369 SMITH 800 ..
7499 ALLEN 1600 ..
7521 WARD 2500 ..
Example:
Output:
enter …empno: 7499
ALLEN 1600
%TYPE:
Syntax:
<variable> <table_name>.<column_name>%TYPE;
Examples:
EMP
v_empno EMP.EMPNO%TYPE;
--empno NUMBER(4)
DECLARE
v_empno EMP.EMPNO%TYPE;
v_ename EMP.ENAME%TYPE;
v_sal EMP.SAL%TYPE;
v_hiredate EMP.HIREDATE%TYPE;
BEGIN
v_empno := &empno;
%ROWTYPE:
Syntax:
<variable> <TABLE_NAME>%ROWTYPE;
Example:
r EMP%ROWTYPE;
r.ename
r.sal r.deptno
SELECT * INTO r FROM emp WHERE empno=7499;
• It decreases no of variables.
Example on %ROWTYPE:
DECLARE
v_empno EMP.EMPNO%TYPE;
r EMP%ROWTYPE;
BEGIN
v_empno := &empno;
%TYPE:
to declare a variable with table column's data type
Ex:
v_empno EMP.EMPNO%TYPE;
%ROWTYPE:
used to hold entire row
r EMP%ROWTYPE;
r.empno
r.ename
Note:
UPDATE, DELETE and INSERT commands syntaxes in
SQL and PL/SQL are same.
DECLARE
v_empno EMP.EMPNO%TYPE;
v_amount FLOAT;
BEGIN
v_empno := &empno;
v_amount := &amount;
dbms_output.put_line('salary increased');
END;
/
Read empno
DELETE command
DECLARE
v_empno EMP.EMPNO%TYPE;
BEGIN
v_empno := &empno;
dbms_output.put_line('record deleted');
END;
/
STUDENT
sid sname m1
DECLARE
r STUDENT%ROWTYPE;
BEGIN
r.sid := &sid;
r.sname := '&sname';
r.m1 := &m1;
dbms_output.put_line('record inserted');
END;
/
v_Exp := trunc((sysdate-v_hiredate)/365)
display message:
DECLARE
v_empno EMP.EMPNO%TYPE;
v_hiredate DATE;
v_exp INT;
BEGIN
v_empno := &empno;
v_exp := TRUNC((sysdate-v_hiredate)/365);
DECLARE
d DATE;
s STRING(10);
BEGIN
d := to_date('&date');
ORACLE 4PM PLSQL Page 21
d := to_date('&date');
s := to_char(d,'DAY');
dbms_output.put_line(s);
END;
/
DECLARE x FLOAT;
ASSIGN x := 12.34;
INTIALIZE x FLOAT := 12.34;
PRINT dbms_output.put_line(x);
READ x := &x;
INSERT
UPDATE
DELETE
DECLARE DECLARE
m INT; m INT;
BEGIN BEGIN
m := 70; m := 70;
Control Structure:
Conditional IF .. THEN
IF .. THEN .. ELSE
IF .. THEN .. ELSIF
NESTED IF
CASE
Looping WHILE
FOR
SIMPLE LOOP
Jumping GOTO
ORACLE 4PM PLSQL Page 23
Jumping GOTO
EXIT WHEN
EXIT
CONTINUE
IF .. THEN:
Syntax:
IF <condition> THEN
--Statements
END IF;
Example:
DECLARE
v_empno EMP.EMPNO%TYPE;
v_hiredate DATE;
v_exp INT;
BEGIN
v_empno := &empno;
v_exp := TRUNC((sysdate-v_hiredate)/365);
IF v_exp>41 THEN
DELETE FROM emp WHERE empno=v_empno;
COMMIT;
dbms_output.put_line('record deleted');
END IF;
END;
/
IF .. THEN .. ELSE:
Syntax:
IF <condition> THEN
--Statements
ELSE
--Statements
END IF;
read empno
select job => v_job
IFv_job='MANAGER' THEN
UPDATE => 20%
ELSE
UPDATE => 10%
END IF;
DECLARE
v_empno EMP.EMPNO%TYPE;
v_job EMP.JOB%TYPE;
v_per INT;
BEGIN v_empno v_job v_per
v_empno := &empno;
7902 ANALYST 10
SELECT job INTO v_job FROM emp WHERE
empno=v_empno;
IF v_job='MANAGER' THEN
v_per := 20;
ELSE
v_per := 10;
END IF;
Assignment:
IF v_sal>10000 THEN
ROLLBACK;
dbms_output.put_line('Tansaction cancelled');
ELSE
COMMIT;
dbms_output.put_line('Tansaction successful');
END IF;
IF .. THEN .. ELSIF:
Syntax:
IF <condition-1> THEN
--Statements
ELSIF <condition-2> THEN
--Statements
.
.
[ELSE
--Statements]
END IF;
read empno
select job => v_job
if v_job='MANAGER' THEN
v_per := 20;
elsif v_job='CLERK' THEN
v_per := 10;
else
v_per := 5;
END IF;
UPDATE salary
commit
Assignment:
NESTED IF:
Writing 'IF' in another 'IF' is called 'Nested If'
Syntax:
IF <condition-1> THEN
IF <condition-2> THEN
inner
outer --Statements condition-1 => T
if
if END IF; condition-2 => T
END IF;
STUDENT RESULT
SID SNAME M1 M2 M3 sid total avrg result
1 A 60 80 70 1 210 70 FIRST
2 B 50 30 90
enter … sid: 1
result stored in result table
COMMIT;
Program:
DECLARE
v_sid STUDENT.SID%TYPE;
r1 STUDENT%ROWTYPE;
r2 RESULT%ROWTYPE;
BEGIN
v_sid := &sid;
r2.total := r1.m1+r1.m2+r1.m3;
r2.avrg := r2.total/3;
switch if else if
can check equality condn only can check any condition
switch(expression)
{
if(x>0)
case <constant-1>:
//STATEMENTS
break;
else if(x<0)
case <constant-2>:
//STATEMENTS
else if(x==0)
break;
.
.
default:
//Statements
}
Simple CASE:
It can check equality condition only
Syntax:
CASE <expression>
WHEN <constant-1> THEN
--Statements
WHEN <constant-2> THEN
--Statements
.
.
[ELSE
--Statements]
END CASE;
Syntax:
CASE
WHEN <condition-1> THEN
--Statements
WHEN <condition-2> THEN
--Statements
.
.
[ELSE
--Statements]
END CASE;
DECLARE
n INT := &n;
BEGIN
CASE mod(n,2)
WHEN 0 THEN
dbms_output.put_line('EVEN');
WHEN 1 THEN
dbms_output.put_line('ODD');
END CASE;
END;
/
Assignment:
program to increase salary of given empno based on
joining year:
if emp joined in 1980, increase 22.5% on sal
if emp joined in 1981, increase 13.5% on sal
ORACLE 4PM PLSQL Page 32
if emp joined in 1981, increase 13.5% on sal
if emp joined in 1982, increase 10.2% on sal
others, increase 8% on sal
do it using SIMPLE CASE
CASE to_char(hiredate,'YYYY')
WHEN 1980 THEN
v_per := 22.5;
.
.
n=0
n>0
n<0
zero
positive
negative
DECLARE
n INT := &n;
BEGIN
CASE
WHEN n>0 THEN
dbms_output.put_line('positive');
WHEN n<0 THEN
dbms_output.put_line('negative');
WHEN n=0 THEN
dbms_output.put_line('zero');
END CASE;
END;
/
Assignment:
CASE
WHEN sal>=10000 THEN
v_per := 20;
WHEN sal>=5000 THEN
v_per := 15.5;
WHEN sal<5000 THEN
v_per := 5.3;
END CASE;
UPDATE
100 hellos
100 times
d_o.p_l('hello'); hello
LOOP 100 times
d_o.p_l('hello'); hello
d_o.p_l('hello');
d_o.p_l('hello'); hello
END LOOP;
. .
. .
d_o.p_l('hello'); hello
d_o.p_l('hello'); hello
d_o.p_l('hello'); hello
• WHILE
• SIMPLE LOOP
• FOR
WHILE:
Syntax:
ORACLE 4PM PLSQL Page 34
Syntax:
In C:
WHILE <condition>
LOOP while(<condition>)
--Statements {
END LOOP; //Statements
}
Example on WHILE:
i DECLARE
1 i INT;
2 BEGIN
3 i := 1;
4
. dbms_output.put_line(i); --1
. i:=i+1; --i=2
100
dbms_output.put_line(i); --2
i:=i+1; --i=3
dbms_output.put_line(i); --3
i:=i+1; --i=4
dbms_output.put_line(i); --4
END;
/
i
WHILE i<=4
1
LOOP
2
dbms_output.put_line(i);
ORACLE 4PM PLSQL Page 35
WHILE i<=4
1
LOOP
2
dbms_output.put_line(i);
3
i:=i+1;
4
LOOP;
i<=4
Program:
declare
i INT;
begin
i := 1;
WHILE i<=4
LOOP
dbms_output.put_line(i);
i := i+1;
END LOOP;
end;
/
d1 d2
1-jan-2023 31-dec-2023
WHILE d1<=d2
LOOP
d_o.p_l(d1);
d1:=d1+1;
END LOOP
Program:
DECLARE
d1 DATE := '1-JAN-2023';
d2 DATE := '31-DEC-2023';
BEGIN
WHILE d1<=d2
ORACLE 4PM PLSQL Page 36
WHILE d1<=d2
LOOP
dbms_output.put_line(d1 || ' ' || to_char(d1,'DY'));
d1 := d1+1;
END LOOP:
END;
/
DECLARE
d1 DATE := '1-JAN-2023';
d2 DATE := '31-DEC-2023';
BEGIN
WHILE d1<=d2
LOOP
IF to_char(d1,'DY') = 'SUN' THEN
dbms_output.put_line(d1 || ' ' || to_char(d1,'DY'));
END IF;
d1 := d1+1;
END LOOP;
END;
/
Simple Loop:
Syntax:
LOOP
--Statements
EXIT WHEN <condition>; [or] EXIT;
END LOOP;
Note:
EXIT WHEN / EXIT are same as "break" in C / Java.
ORACLE 4PM PLSQL Page 37
EXIT WHEN / EXIT are same as "break" in C / Java.
EXIT WHEN:
• it is used to terminate the loop in the middle of
execution
• It can be used in "LOOP" Only.
Syntax:
EXIT WHEN <condition>;
EXIT:
• it is used to terminate the loop in the middle of
execution.
• It can be used in "LOOP" Only.
Syntax:
EXIT;
BEGIN
dbms_output.put_line('HI');
EXIT;
dbms_output.put_line('BYE');
END;
/
i DECLARE
1 i INT;
2 BEGIN
3 i := 1;
4
LOOP
dbms_output.put_line(i);
FOR LOOP:
Syntax:
i
BEGIN
1 FOR i IN 1 .. 4
2 LOOP
3 dbms_output.put_line(i);
4 END LOOP;
END;
/
Note:
Example:
BEGIN
FOR i IN 1 .. 10 Output:
ERROR:
ORACLE 4PM PLSQL Page 39
BEGIN
FOR i IN 1 .. 10 Output:
LOOP ERROR:
i := 5; "I" loop variable is read-only variable
dbms_output.put_line(i);
END LOOP;
END;
/
Example:
BEGIN
FOR i IN 1 .. 5
LOOP
dbms_output.put_line(i);
END LOOP;
dbms_output.put_line(i); --ERROR: loop variable cannot be accessed out of loop
END;
/
Example:
BEGIN
FOR i IN 1 .. 20
LOOP
dbms_output.put_line(i);
i := i+2; --ERROR
END LOOP;
END;
/
GOTO:
Syntax:
<<LABEL>>
GOTO LABEL;
Example on GOTO:
DECLARE
i
i INT := 1;
1 BEGIN
2
3 <<xyz>>
4 dbms_output.put_line(i);
i := i+1;
IF i<=4 THEN
GOTO xyz;
END IF;
END;
/
CONTINUE:
• It is used to skip current iteration and continue the next
iteration.
• CONTINUE can be used in LOOP only.
BEGIN
dbms_output.put_line('HI');
continue;
dbms_output.put_line('BYE');
END;
Output:
ERROR: Continue can be used in LOOP only
Example on Continue:
1 BEGIN
2 FOR i IN 1 .. 10
3 LOOP
4 IF i=7 THEN
5 continue;
6 END IF;
8 dbms_output.put_line(i);
9 END LOOP;
10 END;
/
CURSOR:
v_empno EMP.EMPNO%TYPE;
emp r EMP%ROWTYPE;
empno ename sal
1001 A 5000 r
1002 B 7000
1003 C 6000 empno ename sal
GOAL:
• used to hold multiple rows & process them one by one
CURSOR:
• CURSOR is a pointer to the memory location in ORACLE INSTANCE [RAM]. This
memory location has multiple rows.
• To hold multiple rows & process them one by one, we use CURSOR
ORACLE DB SERVER
INSTANCE DB
PL/SQL 1
Program 2
SELECT ename,sal
c1 FROM emp ename sal emp
A 5000 dept
.
B 6000
.
4. C 7000
address gives to c1
4 steps:
• DECLARE
• OPEN
• FETCH
• CLOSE
Declaring Cursor:
ename sal
Syntax:
SMITH 800
CURSOR <name> IS <SELECT query>; ALLEN 1600
WARD 2450
Example:
CURSOR c1 IS SELECT ename,sal FROM emp;
c1
Opening Cursor:
Syntax:
OPEN <cursor_name>;
Example:
OPEN c1; ORACLE DB SERVER
2 goes to DB
Instance DB
` 4
memory location address
ORACLE 4PM PLSQL Page 44
ALLEN 1600
WARD 2450
` 4
memory location address RAM HARD DISK
will be given to c1
3
selects data & copies
into instance
c1 Instance
Fetching Record from Cursor:
Syntax: BFR
SMITH 800
FETCH <cursor_name> INTO <variable_list>;
ALLEN 1600
WARD 2450
ALR
Example:
FETCH c1 INTO v_ename, v_sal;
stop BFR => Before First Row
when ALR => After Last Row
fetch
is
unsuccessful
NOTE:
One FETCH statement can fetch 1 row only.
To FETCH multiple rows write FETCH statement in LOOP.
CLOSE <cursor_name>;
SMITH 800
ALLEN 1600
WARD 2450
Example:
CLOSE c1;
Cursor Attributes:
• %FOUND
• %NOTFOUND
• %ISOPEN
• %ROWCOUNT
<cursor_name><attribute_name>;
%FOUND %NOTFOUND %ROWCOUNT
Examples: 0
c1%FOUND
c1%NOTFOUND c1 Instance
c1%ISOPEN BFR
c1%ROWCOUNT
SMITH 800
%NOTFOUND:
• It returns boolean value.
• If record is not found, it returns TRUE.
• If record is found, it returns FALSE.
%ISOPEN:
• it returns boolean value
• it is used to check whether the cursor is opened or not.
• if cursor is opened, it returns TRUE.
• if cursor is not opened, it returns FALSE.
%ROWCOUNT:
• it returns row number.
• its default value is 0.
• When fetch is successful, it will be incremented by 1.
Examples on CURSOR:
DECLARE
CURSOR c1 IS SELECT ename,sal FROM emp;
v_ename EMP.ENAME%TYPE;
Instance
v_sal EMP.SAL%TYPE; c1
BEGIN v_ename v_sal BFR
OPEN c1; SMITH 800
ALLEN 1600
LOOP
WARD 2450
FETCH c1 INTO v_ename, v_sal;
EXIT WHEN c1%NOTFOUND;
dbms_output.put_line(v_ename || ' ' || v_sal);
END LOOP;
CLOSE c1;
END;
/
EMPLOYEE HIKE
empno ename sal empno per
1001 A 6000 1001 10
1002 B 5000 1002 20
1003 C 7000 1003 15
commit;
Program:
DECLARE
CURSOR c1 IS SELECT * FROM hike; Instance
r HIKE%ROWTYPE; c1
r
BEGIN BFR
empno per
OPEN c1;
1003 15 1001 10
LOOP 1002 20
FETCH c1 INTO r; 1003 15
EXIT WHEN c1%notfound;
UPDATE employee SET sal=sal+sal*r.per/100 WHERE empno=r.empno;
END LOOP;
c1%notfound
COMMIT;
STUDENT
sid sname m1 m2 m3 RESULT
1001 A 50 80 70 sid total avrg result
1002 B 78 30 60
LOOP 1002 B 78 30 60
FETCH c1 INTO r1;
EXIT WHEN c1%NOTFOUND; TRUE
r1
r2.total := r1.m1+r1.m2+r1.m3;
sid sname m1 m2 m3
r2.avrg := r2.total/3; 1002 B 78 30 60
COMMIT;
dbms_output.put_line('result calculated and stored in result table');
CLOSE c1;
END;
/
DECLARE
CURSOR c1 IS SELECT ename,sal FROM emp;
BEGIN
FOR r IN c1
LOOP
dbms_output.put_line(r.ename || ' ' || r.sal);
END LOOP;
END;
/
Inline Cursor:
If SELECT query is specified in cursor for loop then it is
called "Inline Cursor".
Syntax:
BEGIN
FOR r IN (SELECT ename,sal FROM emp)
LOOP
dbms_output.put_line(r.ename || ' ' || r.sal);
END LOOP;
END;
/
v_sum
SAL v_sal
c1 0 5000 9000 15000
5000
4000
6000
print v_Sum
DECLARE
CURSOR c1 IS SELECT sal FROM emp;
v_sum FLOAT := 0;
v_sal EMP.SAL%TYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO v_sal;
EXIT WHEN c1%NOTFOUND;
v_sum := v_sum + NVL(v_sal,0);
END LOOP;
dbms_output.put_line('sum=' || v_sum);
CLOSE c1;
END;
/
Assignment:
Find max salary in all emps using CURSOR:
v_max
v_sal
SAL
0 5000 6000
5000
c1
4000
6000 IF v_sal>v_max THEN
v_max := v_sal;
END IF;
PRINT v_max
dbms_output.put_line(RTRIM(s,','));
SMITH,ALLEN,WARD
DECLARE
CURSOR c1 IS SELECT ename FROM
emp;
s STRING(500) := '';
v_ename EMP.ENAME%TYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO v_ename;
EXIT WHEN C1%NOTFOUND;
s:= s || v_ename || ',';
END LOOP;
dbms_output.put_line(RTRIM(s,','));
CLOSE c1;
END;
/
Syntax:
LISTAGG(<column>,<delimiter>)
[WITHIN GROUP(ORDER BY <column> ASC/DESC)]
Examples on LISTAGG():
Concatenate all emp names by separate them using ,:
ename
---------
SMITH SMITH,ALLEN,WARD
ALLEN
WARD
SELECT deptno,
LISTAGG(ename,',') WITHIN GROUP(ORDER BY ename ASC)as enames
FROM emp
GROUP BY deptno;
Parameterized Cursor:
• A cursor which is declared using parameter is called "Parameterized
Cursor".
Example:
CURSOR c1(n NUMBER) IS SELECT * FROM emp
WHERE deptno=n;
Ex:
OPEN c1(20);
DECLARE
CURSOR c1(n NUMBER) IS SELECT * FROM emp
WHERE deptno=n;
r EMP%ROWTYPE;
BEGIN
OPEN c1(20);
LOOP
FETCH c1 INTO r;
EXIT WHEN C1%NOTFOUND;
dbms_output.put_line(r.ename || ' ' || r.sal || ' ' || r.deptno);
END LOOP;
DECLARE
CURSOR c1 IS SELECT sal FROM emp;
v_sum FLOAT := 0;
BEGIN
FOR r IN c1
LOOP
v_sum := v_sum + NVL(r.sal,0);
END LOOP;
dbms_output.put_line('sum=' || v_sum);
END;
/
Ref Cursor:
• In Simple Cursor, One CURSOR can be used for one SELECT query only.
• In Ref Cursor, one CURSOR can be used for multiple SELECT queries.
Syntax:
<cursor_name> SYS_REFCURSOR;
Example:
c1 SYS_REFCURSOR;
Syntax:
Example:
OPEN c1 FOR SELECT * FROM emp;
.
.
OPEN c1 FOR SELECT * FROM dept;
Program to display all emp table records and dept table records:
DECLARE
Loop
FETCH c1 INTO r1;
EXIT WHEN c1%NOTFOUND;
dbms_output.put_line(r1.ename || ' ' || r1.sal);
End Loop;
CLOSE c1;
LOOP
FETCH c1 INTO r2;
EXIT WHEN c1%notfound;
dbms_output.put_line(r2.deptno || ' ' || r2.dname || ' ' || r2.loc);
END LOOP;
CLOSE c1;
END;
/
• One Cursor can be used for • Same Cursor can be used for multiple
1 SELECT query only. SELECT queries.
• It is static. • It is Dynamic.
SELECT query is fixed SELECT query can be changed
Types of Cursors:
2 Types:
• Implicit Cursor
• Explicit Cursor
Implicit Cursor:
• A cursor which is defined implicitly by ORACLE is called
"Implicit Cursor".
• To process any DRL command or DML command a Cursor
will be used implicitly.
• This Implicit Cursor name is: SQL
BEGIN
UPDATE emp SET sal=sal+1000;
dbms_output.put_line(SQL%ROWCOUNT || ' rows updated');
END;
/
• Explicit Cursor:
A cursor which is defined explicitly by user is called
2 Types:
• Simple Cursor
• Ref Cursor
CURSOR:
GOAL: to hold multiple rows & process them one by one
4 steps:
DECLARE CURSOR c1 IS SELECT * FROM emp;
OPEN OPEN c1;
FETCH FETCH c1 INTO r;
Inline Cursor:
we specify select query in cursor for loop
Parameterized Cursor:
• A cursor which is declared with parameter
• At the time of opening cursor we pass value to cursor
parameter
Ref Cursor:
Same cursor can be used for multiple SELECT queries
Cursor Attributes:
%FOUND
%NOTFOUND
%ISOPEN
%ROWCOUNT
Types of Errors:
3 Types:
Examples:
missing ;
missing )
missing '
Logical Error:
• This error occur due to mistake in logic.
• Due to logic mistake, it gives wrong result.
• Programmer is responsible for writing correct logic.
Example:
withdraw
v_balance := v_balance + v_amount
DECLARE
--declare the variables
BEGIN
--executable statements
EXCEPTION
WHEN <exception_name> THEN
--Handling Code
WHEN <exception_name> THEN
--Handling Code
.
.
END;
/
DECLARE
x NUMBER(4);
y NUMBER(4);
z NUMBER(4);
BEGIN
x := &x;
y := &y;
z := x/y;
dbms_output.put_line('quotient=' || z);
EXCEPTION
WHEN zero_divide THEN
dbms_output.put_line('you cannot divide with 0');
WHEN value_error THEN
dbms_output.put_line('wrong input or value out of range');
WHEN others THEN
dbms_output.put_line('Run Time Error Occurred');
ORACLE 4PM PLSQL Page 62
dbms_output.put_line('Run Time Error Occurred');
END;
/
Output:
enter value for x: 10
enter value for y: 2
quotinet=5
Output:
enter value for x: 10
enter value for y: 2
quotient=5
Output:
enter value for x: 10
enter value for y: 0
you cannot divide with 0
Output:
enter value for x: 123456
enter value for y: 2
wrong input or value out of range
Output:
enter value for x: 'raju'
enter value for y: 2
wrong input or value out of range
OTHERS:
It can handle any type of exception
Example On Others:
DECLARE
x NUMBER(4);
y NUMBER(4);
z NUMBER(4);
BEGIN
x := &x;
y := &y;
z := x/y;
dbms_output.put_line('quotient=' || z);
Output:
enter value for x: 10
enter value for y: 2
quotient=5
Output:
enter value for x: 10
enter value for y: 0
Run Time Error Occured
Output:
enter value for x: 123456
enter value for y: 2
Run Time Error Occured
Output:
enter value for x: 'raju'
enter value for y: 2
Run Time Error Occured
Types of Exceptions:
2 Types:
Examples:
zero_divide
value_error
no_data_found
dup_val_on_index
too_many_rows
User-Defined Exception:
• The exception which is defined by the user is called "User-
Defined Exception".
• We can define our exceptions. These are called "User-Defined
Exceptions".
• User-Defined Exception must be raised explicitly using RAISE
keyword.
Examples:
Sunday_Not_Allow
One_Divide
Invalid_Marks
xyz
Built-In Exceptions:
zero_divide:
When we try to divide with zero, zero_divide exception will
be raised.
Example:
z := 5/0; --raises zero_divide exception
value_error:
when we give wrong input or when value is out of range then
value_error exception will be raised.
Examples:
x NUMBER(4);
x := &x;
enter value for x: 123456 => value_error will be raised
x := &x;
enter value for x: 'raju' => value_error will be raised
No_Data_Found:
Example: emp
v_empno := &empno; empno ename
1001
enter value for empno:5678
1002
--No_Data_Found Exception will be raised
..
1010
Example on No_Data_Found:
DECLARE
v_empno EMP.EMPNO%TYPE;
r EMP%ROWTYPE;
BEGIN
v_empno := &empno;
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('employee not existed with this empno');
END;
/
Output:
enter value for empno: 7369
SMITH 3080
Output:
enter value for empno: 1234
employee not existed with this empno
Note:
When Run Time Error Occurs execution goes EXCEPTION block. It searches for
corresponding Exception Name.
Dup_Val_On_Index:
When we try to insert duplicate value in Primary Key Column
then DUP_VAL_ON_INDEX excpetion will be raised.
Example On Dup_Val_On_Index:
DECLARE
r STUDENT%ROWTYPE;
BEGIN
r.sid := &sid;
r.sname := '&sname';
dbms_output.put_line('record inserted');
EXCEPTION
WHEN dup_val_on_index THEN
dbms_output.put_line('PK does not accept duplicate
value');
END;
/
Output:
Enter value for sid: 10
Enter value for sname: AA
record inserted
Output:
Enter value for sid: 10
Enter value for sname: BB
PK does not accept duplicate value
Example on TOO_MANY_ROWS:
Cursor_Already_Open:
If we try to open opened cursor then
CURSOR_ALREADY_OPEN exception will be raised
Example On Cursor_Already_Open:
DECLARE
CURSOR c1 IS SELECT * FROM emp;
r EMP%ROWTYPE;
BEGIN
OPEN c1;
OPEN c1;
LOOP
FETCH c1 INTO r;
EXIT WHEN c1%notfound;
dbms_output.put_line(r.ename || ' ' || r.sal);
END LOOP;
CLOSE c1;
EXCEPTION
WHEN cursor_already_open THEN
dbms_output.put_line('cursor is already opened');
END;
/
Invalid_Cursor:
If we try to fetch the record without opening cursor then
Invalid_Cursor Exception will be raised.
Example on Invalid_Cursor:
DECLARE
CURSOR c1 IS SELECT * FROM emp;
r EMP%ROWTYPE;
BEGIN
CLOSE c1;
EXCEPTION
WHEN invalid_cursor THEN
dbms_output.put_line('cursor not opened');
END;
/
Invalid_Number:
When ORACLE is unable to convert string to number
then Invalid_Number Exception will be raised
Example on Invalid_Number:
BEGIN
INSERT INTO student VALUES(&sid, '&sname', &m1);
COMMIT;
dbms_output.put_line('record inserted');
EXCEPTION
WHEN invalid_number THEN
dbms_output.put_line('expecting number here');
END;
/
Output:
Enter value for sid: 101
Enter value for sname: AA
Enter value for m1: 55
record inserted
Output:
Enter value for sid: 102
Enter value for sname: BB
ORACLE 4PM PLSQL Page 69
Enter value for sname: BB
Enter value for m1: '90'
record inserted
Output:
Enter value for sid: 103
Enter value for sname: CC
Enter value for m1: 'ABC'
expecting number here
Syntax:
<exception_name> EXCEPTION;
Example:
one_divide EXCEPTION;
Syntax:
RAISE <exception_name>;
Example:
RAISE one_divide;
Syntax:
EXCEPTION
WHEN <exception_name> THEN
--Handling Code
Example:
EXCEPTION
WHEN one_Divide THEN
dbms_output.put_line('denominator cannot be 1');
DECLARE
x NUMBER(4);
y NUMBER(4);
z NUMBER(4);
one_divide EXCEPTION;
BEGIN
x := &x;
y := &y;
IF y=1 THEN
z := x/y;
dbms_output.put_line('result=' || z);
EXCEPTION
WHEN one_divide THEN
dbms_output.put_line('denominator cannot be 1');
WHEN zero_divide THEN
dbms_output.put_line('denominator cannot be 0');
END;
/
Output:
Enter value for x: 10
Enter value for y: 2
result=5
Output:
Enter value for x: 10
Enter value for y: 0
denominator cannot be 0
Output:
Enter value for x: 10
Enter value for y: 1
denominator cannot be 1
DECLARE
v_empno EMP.EMPNO%TYPE;
v_amount FLOAT;
sunday_not_allow EXCEPTION;
BEGIN
v_empno := &empno;
v_amount := &amount;
IF to_char(sysdate,'dy')='sun' THEN
dbms_output.put_line('salary increased');
EXCEPTION
WHEN sunday_not_allow THEN
dbms_output.put_line('you cannot update on sunday');
END;
/
on Sunday:
Output:
Enter value for empno: 7369
Enter value for amount: 1000
you cannot update on sunday
Note:
We can raise the error using 2 ways. They are:
• using RAISE keyword
• using RAISE_APPLICATION_ERROR() procedure
RAISE_APPLICATION_ERROR():
• RAISE_APPLICATION_ERROR() is a built-in procedure.
• It is used to raise the error with our own error code and our own error message.
Syntax:
RAISE_APPLICATION_ERROR(user_defined_error_code,
user_defined error_message);
Example:
RAISE_APPLICATION_ERROR(-20050,'divisor cannot be 1');
Example on Raise_Application_Error():
DECLARE
v_empno EMP.EMPNO%TYPE;
v_amount FLOAT;
BEGIN
v_empno := &empno;
v_amount := &amount;
IF to_char(sysdate,'dy')='sun' THEN
RAISE_APPLICATION_ERROR(-20070,'you cannot update on sunday');
END IF;
dbms_output.put_line('salary increased');
END;
/
On Sunday:
Output:
ERROR at line 1:
ORA-20070: you cannot update on sunday
ORA-06512: at line 9
• is a keyword • is a procedure
Example: Example:
RAISE Sunday_not_allow; Raise_Application_Error(-20070,'you cannot update on sunday');
Note:
-1 Error Code
unique constraint violated Error Message
DUP_VAL_ON_INDEX Error Name
Pragma Exception_Init():
• Some errors have name. Some errors does not have name.
• TO define name for unnamed Exception, we use
PRAGMA EXCEPTION_INIT()
Syntax:
PRAGMA EXCEPTION_INIT(<exception_name>, <error_code>)
DECLARE
r STUDENT%ROWTYPE;
check_violate EXCEPTION;
PRAGMA EXCEPTION_INIT(check_violate,-2290);
BEGIN
r.sid := &sid;
r.sname := '&sname';
r.m1 := &m1;
dbms_output.put_line('record inserted');
EXCEPTION
WHEN dup_val_on_index THEN
dbms_output.put_line('PK does not dup value');
WHEN check_violate THEN
dbms_output.put_line('check constraint violated');
END;
/
Example on SQLERRM:
DECLARE
x NUMBER(4);
y NUMBER(4);
z NUMBER(4);
BEGIN
x := &x;
y := &y;
z := x/y;
dbms_output.put_line('result=' || z);
EXCEPTION
WHEN others THEN
dbms_output.put_line(SQLERRM);
END;
/
Types of exceptions:
2 Types:
Built-In Exception already defined by oracle developers
these will be raised implicitly by oracle
Examples:
zero_divide
value_error
no_data_found
too_many_rows
3 steps:
declare
raise
handle
Raise_Application_error():
• is a procedure
• used to raise the error with our own error code & message
Pragma Exception_Init():
some exceptions does not have name
to define name to unnamed exception, we use it
PL/SQL Basics
Control Structures
Coding
Cursors
Exception handling
Procedure:
• Procedure is a named block of statements that gets
executed on calling.
In C:
Example: Function:
dbms_output.put_line('HELLO'); --procedure call is a set of statements
gets executed on calling
dbms_output package
In Java:
put_line() procedure
Method:
is a set of statements
gets executed on calling
PROCEDURE put_line(STRING s) AS
BEGIN
--Statements
END;
Procedure:
• Procedure is a named block of statements that gets
executed on calling.
• Every Procedure is defined to perform specific action.
Examples:
Withdraw Procedure
Deposit Procedure
DELETE_EMP PROCEDURE
Types of Procedures:
2 Types:
• Stored Procedure
• Packaged Procedure
Stored Procedure:
A procedure which is defined in SCHEMA is called
"Stored Procedure / Stand Alone Procedure".
Note:
Example: Schema = user
SCHEMA c##batch4pm
PROCEDURE withdraw => Stored Procedure
Packaged Procedure:
A procedure which is defined in PACKAGE is called
"Packaged Procedure".
Example:
SCHEMA c##batch4pm
PACKAGE bank
PROCEDURE withdraw => Packaged Procedure
Procedure is a Db Object.
3 ways:
• From SQL prompt
• From PL/SQL program [main program]
• From Front-End Application [Java, C#, Python]
EXEC[UTE]:
EXEC command is used to call the procedure from SQL prompt.
DECLARE
a INT;
b INT;
BEGIN
a := &a;
b:=&b;
Note:
A procedure contains 2 parts. They are:
• Procedure Header
Formal Parameters
• Procedure Body
Procedure
CREATE OR REPLACE PROCEDURE Procedure Header
addition(x NUMBER, y NUMBER)
IS +
z NUMBER(4);
BEGIN Procedure Body
z := x+y;
dbms_output.put_line('sum=' || z);
END;
/
Procedure Call:
EXEC addition(2,3); --2,3 => Actual Parameters
Parameter:
• Parameter is a local variable that is declared in Procedure Header
<parameter_name> [<parameter_mode>]<data_type>
parameter modes:
• IN [default]
• OUT
• IN/OUT
Formal Parameter:
A parameter which is declared in procedure header is
called "Formal Parameter"
Actual Parameter:
A parameter which is in procedure call is called "Actual parameter"
Parameter Modes:
IN:
• It is default one. If we don't specify parameter mode default mode
will be taken as IN.
• In Parameter can be also called input parameter.
• It captures input from out of procedure.
• It is used to bring value into procedure from out of procedure.
• In procedure call, it can be variable or constant.
• It is read-only parameter. We cannot change its value.
Example:
CREATE OR REPLACE PROCEDURE
addition(x IN NUMBER, y IN NUMBER)
IS
z NUMBER(4);
BEGIN
x := 100; --ERROR: x is read-only parameter
z := x+y;
dbms_output.put_line('sum=' || z);
END;
/
Output:
procedure created with compilation errors
OUT:
• OUT keyword is used to declare OUT parameter.
• OUT parameter can be also called as Output Parameter.
• It is used to send the result out of the procedure.
• It is read-write parameter.
• In procedure call, it must be variable only. it cannot be constant
IN OUT:
• IN OUT keyword is used to declare it.
IN OUT parameter can be used to bring value into procedure and
ORACLE 4PM PLSQL Page 83
○ IN OUT parameter can be used to bring value into procedure and
same parameter can be used to the result out of procedure.
○ It is read-write parameter.
○ In procedure call, it must be variable only.
Bind Variable:
○ A variable which is declared at SQL prompt is called
Bind variable.
○ Its lifetime is limited to session
○ To use bind variable we use bind operator : [colon]
DECLARE
a NUMBER(4);
b NUMBER(4);
c NUMBER(4);
BEGIN
a := &a;
b := &b;
addition(a,b,c);
dbms_output.put_line('sum=' || c);
END;
/
dbms_output.put_line('salary increased');
END;
/
Assignment:
Define a procedure to delete an employee record
dbms_output.put_line('salary increased');
END;
/
ACCOUNT
AcNo Name Balance
1001 A 500000
1002 B 800000
Procedure:
IF p_amount>v_balance THEN
RAISE_APPLICATION_ERROR(-20050,'
Insufficient Balance');
END IF;
dbms_output.put_line('amount debited');
END;
/
Calling Procedure:
dbms_output.put_line('amount credited');
END;
/
Calling procedure:
Calling procedure:
SQL> print b
B
----------
600000
Assignment:
Define a procedure to transfer the funds from one account to another:
Calling Procedure: 5 25
begin
:a := 5;
SQL> variable a number
end;
SQL> exec :a := 5;
SQL> exec square(:a);
begin
SQL> PRINT a
square(:a);
Output:
end;
ORACLE 4PM PLSQL Page 89
SQL> exec :a := 5;
SQL> exec square(:a);
begin
SQL> PRINT a
square(:a);
Output:
end;
a
---
25
Positional Mapping:
In positional mapping, actual parameter will be mapped with
formal parameter based on position.
Example:
positional mapping
Named Mapping:
In named mapping, actual parameter will be mapped with
formal parameter based on name.
=> Association operator
Example:
Named mapping
Mixed Mapping:
In mixed mapping, actual parameters will be mapped with
Example:
positional named
Example:
procedure calls:
*
ERROR at line 1:
Pragma Autonomous_Transaction:
Main Program
Procedure update_salary
EMP
0 salaries are updated EMPNO ENAME SAL
7369 SMITH 5000
Rollback cancels Procedure action and main 7499 ALLEN 3000
action. Because, the transaction started in main
program applied for procedure
Main Program
Procedure update_salary
EMP
EMPNO ENAME SAL
1 salary updated 7369 SMITH 5000
7499 ALLEN 3000 4000
main program:
BEGIN
UPDATE emp SET sal=sal+1000 WHERE empno=7499;
update_salary(7369,2000);
COMMIT;
END;
/
main program:
BEGIN
UPDATE emp SET sal=sal+1000 WHERE empno=7499;
update_salary(7369,2000);
COMMIT;
END;
/
Dropping a procedure:
Syntax:
DROP PROCEDURE <procedure_name>;
Example:
DROP PROCEDURE update_salary;
c##batch4pm:
PROCEDURE update_salary
EXEC update_salary(7369,2000); --procedure call
c##batch8pm
EXEC c##batch4pm.update_salary(7499,1000);
--ERROR: no permission
EXEC c##batch4pm.update_salary(7499,1000);
Output:
salary increased
user_procedures:
• it is a system table / predefined table / readymade table.
• It maintains all procedures, functions, packages and triggers
information
DESC user_procedures;
user_source:
• It is a system table / readymade table.
• It maintains all procedures, functions, packages and
triggers information
DESC user_source;
Note:
Within the Schema procedure name must be unique
Note:
To perform DML operation, define PROCEDURE.
Advantages of Procedure:
• improves the performance. It holds compiled code
• provides reusability
• reduces length of code
• provides security. authorized users only call the procedure
• better maintenance
Note:
• Procedure may or may not return the value.
• Returning value is optional in procedure.
• To return value in procedure, we use OUT parameter.
• A procedure can return multiple values.
Function:
• Function is a named block of statements that gets executed on calling.
Examples:
Opening_Account => INSERT => PROCEDURE
Withdraw => UPDATE => PROCEDURE
Deposit => UPDATE => PROCEDURE
Closing_Account => DELETE => PROCEDURE
Types of Functions:
2 Types:
Stored Function:
• A function which is defined in SCHEMA is called "Stored Function".
Example:
SCHEMA c##batch4pm
FUNCTION check_balance => Stored Function
Packaged Function:
• A function which is defined in PACKAGE is called "Packaged Function".
Example:
SCHEMA c##batch4pm
PACKAGE bank
FUNCTION check_balance => Packaged Function
Open sqlplus
Oracle DB
compile the function as following:
SQL> @d:\ora4pm\FunctionDemo.sql
Function Product
Output:
Function created ……….
………..
compiled code
Calling a Function:
Output:
20
DECLARE
dbms_output.put_line('product=' || c);
END;
/
ACCOUNT
ACNO NAME BALANCE
1001 A 600000
1002 B 900000
RETURN v_balance;
END;
/
Calling Function:
CHECK_BALANCE(1002)
-------------------
900000
RETURN TRUNC((sysdate-v_hiredate)/365);
END;
/
Calling Function:
Output:
EXPERIENCE(7900)
----------------
41
Output:
empno ename sal experience
----------- ------------ ------- -------------------
7369 42
7499 42
RETURN c1;
END;
/
Calling Function:
Output:
--displays 20th dept emp records
RETURN c1;
END;
/
Calling Function:
Output:
--displays top 3 salaried emp records
Procedure Function
OUT parameter is used to return the RETURN keyword is used to return the
value value
Dropping Function:
Syntax:
DROP FUNCTION <name>;
Example:
DROP FUNCTION product;
user_procedures:
It maintans all procedures, functions, packages and triggers
information
user_source:
It maintans all procedures, functions, packages and triggers
information
• provides reusability.
• reduces length of code.
• security.
• improves the performance.
• Better Maintenance.
PACKAGE:
• PACKAGE is a Database Object.
• PACKAGE is a collection of procedures, functions
and variables … etc.
Example:
PACKAGE bank
Creating a Package:
PACKAGE math
PROCEDURE addition
FUNCTION product
PROCEDURE insert_emp
PROCEDURE update_salary
PROCEDURE delete_emp
FUNCTION experience
RETURN TRUNC((sysdate-v_hiredate)/365);
END experience;
END;
/
HR.EXPERIENCE(7902)
-------------------
41
Assignment:
PACKAGE bank
Advantages of Packages:
Note:
• Stored procedures or Stored Functions cannot be overloaded
Packaged procedure or Packaged Function can be overloaded
ORACLE 4PM PLSQL Page 112
• Packaged procedure or Packaged Function can be overloaded
Function Overloading:
• Defining multiple functions with same name and different
signature is called "Function Overloading".
Examples:
change in no of parameters:
Function f1(x INT, y INT)
FUNCTION f1(x INT, y INT, z INT)
Example on Overloading:
PACKAGE mymath
Package Specification:
Package Body:
MYMATH.ADDITION(2,3)
--------------------
5
MYMATH.ADDITION(1,2,3)
----------------------
6
DECLARE
a INT;
b INT;
BEGIN
a := &a;
b := mymath.x + a;
dbms_output.put_line('sum=' || b);
END;
/
Dropping package:
Example:
user_procedures:
SELECT object_name,procedure_name,object_type
FROM user_procedures
WHERE object_type='PACKAGE';
user_source:
ORACLE DB SEREVR
Instance DB 20 times
call p1 p1,p2,…..p10
f1,f2,…..f10
call p2
10 stored procedures
10 stored functions
Instance DB 1 time
PACKAGE SPECIFICATION
DEMO PACKAGE BODY DEMO
TRIGGER:
PROCEDURE update_Salary
Procedure call call
…….
EXEC update_salary(7369,1000); ………
……..
DML
calls TRIGGER t1
UPDATE
……..
……
……..
DELETE
TRIGGER:
• TRIGGER is a named block of statements that gets
executed automatically when we submit DML command.
Note:
• TO perform DML operations define PROCEDURE
• To control DML operations define TRIGGER
EMP
TRIGGER t1
Trigger can be used for 3 purposes:
Example:
○ Don't allow the user to perform DMLs on sunday
○ After /Before working hours don't allow DMLs [office timings: 10AM to
4PM]
• don't allow anyone to update empno
Example:
user
at which date and time
operations
old data
new data
Example:
• don't allow the user to decrease salary
• don't allow the duplicates
• don't allow the nulls
Types of Triggers:
3 Types:
Example:
UPDATE emp SET sal=sal+1000
WHERE job='MANAGER';
Output:
3 rows updated
Example:
UPDATE emp SET sal=sal+1000
WHERE job='MANAGER';
Output:
3 rows updated
Trigger Specification /
Trigger Header
Output:
statement level trigger executed
3 rows updated
Output:
3 rows updated
Syntax:
ALTER TRIGGER <name> <enable/disable>;
Example:
ALTER TRIGGER t2 disable;
Testing:
On Monday:
UPDATE emp SET sal=sal+1000;
Output:
12 rows updated
On Sunday:
UPDATE emp SET sal=sal+1000;
Output:
ERROR:
ORA-20050: you cannot perform DMLs on sunday
ORA-06512: at "C##BATCH4PM.T3", line 3
END;
/
Testing:
before 10am or after 4pm:
update emp set sal=sal+1000;
Output:
ERROR:
ORA-20050: DMLs allowed between 10AM to 4PM only
ORA-06512: at "C##BATCH4PM.T4", line 7
Output:
12 rows updated
Assignment:
d := to_char(sysdate,'d')
h := to_char(sysdate,'hh24')
EMP_Resign
:OLD
empno ename job sal
7900 .. .. ..
Testing:
Output:
1 row deleted.
Output:
EMPNO ENAME JOB SAL DOR
---------- ---------- ---------- ---------- ---------
7900 JAMES CLERK 7950 10-JUL-23
Note:
Don't use COMMIT or ROLLBACK in Trigger.
Testing:
UPDATE emp SET empno=1001
WHERE empno=7369;
Output:
ERROR:
ORA-20050: you cannot update empno
ORA-06512: at "C##BATCH4PM.T6", line 2
NOTE:
BEFORE UPDATE we cannot update any column value
BEFORE UPDATE OF empno we cannot update empno
BEFORE UPDATE OF empno,ename BEFORE UPDATE OF empno and ename
EMP_AUDIT
user_name op_date_time op_type old_Empno old_ename old_sal new_empno new_ename new_sal
Testing:
COMMIT;
EMP
EMPNO ENAME SAL :old
7499 ALLEN 12000 EMPNO ENAME SAL
7369 .. .. 7499 ALLEN 12000
7521 .. ..
:new
UPDATE emp EMPNO ENAME SAL
SET sal=sal-2000 7499 ALLEN 10000
WHERE empno=7499;
Testing:
update emp set sal=sal-5000;
Output:
ERROR:
ORA-20070: You cannot decrease the salary
ORA-06512: at "C##BATCH4PM.T8", line 3
• It is defined by DBA.
Login as DBA:
username: system
password: nareshit
Testing:
Login as c##batch4pm:
Login as DBA:
Testing:
Testing:
Log in as c##batch4pm:
Output:
ERROR
Compound Trigger:
• Introduced in ORACLE 11g.
• Compound Trigger is a set of triggers.
Example:
EMP Table
BEFORE STATEMENT IS
BEGIN
NULL; -- Do something here.
END BEFORE STATEMENT;
AFTER STATEMENT IS
BEGIN
NULL; -- Do something here.
END AFTER STATEMENT;
END <trigger-name>;
/
BEFORE STATEMENT IS
BEGIN
dbms_output.put_line('before statement
level trigger executed');
END BEFORE STATEMENT;
AFTER STATEMENT IS
BEGIN
dbms_output.put_line('after statement
level trigger executed');
END AFTER STATEMENT;
END t12;
/
Testing:
Output:
before statement level trigger executed
before row level trigger executed
after row level trigger executed
before row level trigger executed
after row level trigger executed
after statement level trigger executed
2 rows updated.
Dropping A Trigger:
Syntax:
DROP TRIGGER <trigger_name>;
Example:
DROP TRIGGER t12;
user_triggers:
• is a system table
• it maintains all triggers information
• it maintains the table name, column name, trigger type ..etc
DESC user_triggers;
user_source:
Calling procedure:
SQL> exec drop_table('dept');
dept table dropped
Calling procedure:
LOOP
FETCH c1 INTO n;
EXIT WHEN c1%NOTFOUND;
EXECUTE IMMEDIATE 'DROP TABLE ' || n || ' cascade constraints';
END LOOP;
CLOSE c1;
END;
/
Procedure Call:
EXEC drop_all_tables
BFILE:
• BFILE stands for Binary File Large Object.
Database
EMP1 D: Drive
EMPNO ENAME EPHOTO [BFILE] Images Folder
1001 Ravi bfilename('D1','Ravi.jpg')
Ravi.jpg
D1 = D:\Images
bfilename():
• it is a function
• it is used to maintain multimedia object's path
Syntax:
bfilename(<directory_object>, <file_name>)
Example:
ORACLE 4PM PLSQL Page 136
Example:
bfilename('D1','Ravi.jpg')
Directory Object:
• It is a Database Object
• It is a pointer to particular folder
Login as DBA:
username: system
password: nareshit
Login as c##batch4pm:
• It is secured one.
Database
D: Drive
EMP2 Images Folder
EMPNO ENAME EPHOTO [BLOB]
1001 Ravi 57A23F456E123A
Ravi.jpg
Example on BLOB:
number null
char ''
blob empty_blob() =>
• it is a function
• inserts null in blob type column
DBMS_LOB package
• Select the LOB LOCATOR and copy into t variable [BLOB type]
and Lock the record
s BFILE;
s := bfilename('D1','ellison.jpg');
dbms_lob.open(s, dbms_lob.lob_readonly);
length number;
length := dbms_lob.getlength(s); //5683 [no of bytes]
dbms_lob.LoadFromFile(t,s,length);
now t has s image's binary data
dbms_lob.close(s);
s := bfilename('D1',n);
dbms_lob.open(s, dbms_lob.lob_readonly);
length := dbms_lob.getlength(s);
dbms_lob.loadfromfile(t,s,length);
dbms_lob.close(s);
procedure call:
EXEC update_photo(1001,'ellison.jpg');
LENGTH(EPHOTO)
--------------
5683
x INT; 20 30
x:=20;
.
.
x:=30;
Collection:
• Collection is a set of elements of same type.
Example:
50 90 70 60 80
x(1) x(2) x(3) x(4) x(5)
Types of Collections:
3 Types:
INDEX ELEMENT
[KEY] [VALUE]
1 50
2 80
3 40
4 90
follow 2 steps:
• Define data type for associative array
• Declare variable for that associative array
Example:
TYPE num_array IS TABLE OF NUMBER(4) INDEX BY binary_integer;
Note:
INDEX ELEMENT If index is number type then we can use
1 10 binary_integer or pls_integer
2 70
3 50
Syntax:
<name> <collection_type>;
Example:
x NUM_ARRAY;
x NUMBER(4);
y VARCHAR2(10);
DECLARE
TYPE num_array IS TABLE OF NUMBER(4) INDEX BY binary_integer;
x NUM_ARRAY;
BEGIN x => associative array
x(1) := 50;
INDEX ELEMENT
x(2) := 90;
1 50
x(3) := 70;
2 90
FOR i IN x.first .. x.last 3 70
LOOP
dbms_output.put_line(x(i));
END LOOP;
Output:
50
90
70
first index=1
last index=3
prev index of 2=1
next index of 2=3
INDEX ELEMENT
1 ACCOUNTING
2 RESEARCH
3 SALES
4 OPERATIONS
DECLARE
PL/SQL Program
PL/SQL Engine
SQL statements
PL/SQL statement executor
PL/SQL statements
DECLARE
TYPE dept_array IS TABLE OF varchar2(10) INDEX BY
binary_integer;
d DEPT_ARRAY;
BEGIN
SELECT dname BULK COLLECT INTO d FROM dept;
INDEX ELEMENT
emp%rowtype
binary_integer
DECLARE
TYPE emp_array IS TABLE OF emp%rowtype INDEX BY
binary_integer;
e EMP_ARRAY;
BEGIN
employee HIKE
empno ename sal EMPNO PER
1001 A 6000 1001 10
1002 B 5000 1002 20
1003 C 7000 1003 15
INDEX ELEMENT
empno per
1
1001 10
hike%rowtype
empno per
binary_integer 2 1002 20
empno per
3
1003 15
DECLARE
TYPE hike_array IS TABLE OF hike%rowtype INDEX BY pls_integer;
h HIKE_ARRAY;
BEGIN
In Above Example,
For loop will be executed by PL/SQL statement executor.
UPDATE command will be executed by SQL statement executor.
BULK BIND:
• For BULK BIND, we use FORALL.
Syntax of FORALL:
Example:
DECLARE
TYPE hike_array IS TABLE OF hike%rowtype INDEX BY pls_integer;
h HIKE_ARRAY;
BEGIN
In above program, with 1 context switch all emp records will be updated.
It improves the performance.
Example:
x(1)
10
20
90
50
Syntax:
TYPE <type_name> IS TABLE OF <elent_type>;
Example:
TYPE num_array IS TABLE OF NUMBER(4);
Syntax:
<variable> <type>;
Ex:
x NUM_ARRAY;
DECLARE
TYPE num_array IS TABLE OF number(4);
x NUM_ARRAY;
BEGIN
x := num_array(10,50,90,30,40);
END;
/
DECLARE
TYPE emp_array IS TABLE OF emp%rowtype;
V-Array:
• V-Array => Variable Size Array
Syntax:
TYPE <type_name> IS VARRAY(<size>) OF <element_type>;
Example:
TYPE num_array IS VARRAY(10) OF NUMBER(4);
Syntax:
<variable> <data_type>;
Example:
x NUM_ARRAY;
Example on V-Array:
DECLARE
TYPE num_array IS VARRAY(10) OF NUMBER(4);
x NUM_ARRAY;
DECLARE
TYPE emp_array IS VARRAY(20) OF emp%rowtype ;
e EMP_ARRAY;
BEGIN
SELECT * BULK COLLECT INTO e FROM emp;
CURSOR COLLECTION
• Slower • Faster
sparse dense
x(10) x(1)
x(20) x(2)
x(30) x(3)
x(37) x(4)