Académique Documents
Professionnel Documents
Culture Documents
####################
# PL/SQL #
####################
Before going to start PL/SQL first we will discuss what is sql and pl/sql
ADVANTAGES OF PL/SQL:
1> Tight integration with sql
-> pl/sql is tightly integrated with sql. the most widely used database
manipulation language
-> pl/sql lets us use all sql DML,TCL statements and all sql functions,
operators, pseudo columns...
-> pl/sql fully supports sql datatypes
2> High Performance
-> in sql only one statement can be executed at at time
-> in pl/sql multiple statements can be executed at a time
-> each time an sql statement is executed, a call is made to the server
resources. this leads to network traffic due to this decreasing the data
processing speed especially in multiuser environment.
-> pl/sql allows us to group of sql statements together with in a single
block and to send the entire block to the server in a single call, there by
network traffic is reduced and increased the performance
3> High productivity
PL/SQL BLOCK
/ \
NAMED BLOCK UN-NAMED OR ANONYMOUS
Named:
These blocks are possible to store in the db by giving a name to
block.
--> calling the named pl/sql block is possible.
Unamed or anonymous:
Storing un-named or anonymous blocks is not possible
--> calling un-named pl/sql block is not possible
Declaration Section:
its an optional section
in this section we declare variables, cursors, exceptions, constants,..etc
Executable Section:
it is a manadatory section
declare -->optional
variable declaration;
begin -->Mandatory
executable statements;
exception -->Optional
exception handlers;
end;
/
Note: A pl/sql block ends with 'end;'
Variable:
a variable is a object which can hold a value
the value may change at the time of execution of a pl/sql block
Types of variables:
we have two types of variables
1. pl/sql variables
2. Non pl/sql variables
Pl/sql variables:
The variables which are declared with in a pl/sql block are called
pl/sql variables.
Non-pl/sql[host/bind]variables:
the varaibles which are declared outside of the pl/sql block called
non pl/sql or host or bind variables.
Datatypes:
-- data types are of four types
1. scalar 2.composite 3.lob 4.ref-cursor
'Scalar':
the datatype which can hold only one value is called scalar datatype
ex: char,varchar,date,number,...etc.
in scalar datatypes again we have boolean, %type datatypes.
'Composite':
its a collection of more than one datatype
here we have %rowtype
declare
a number:=10;
b number:=20;
c number;
begin
c:=a+b;
dbms_output.put_line(c);
end;
/
ex2: printing user defined message in output.
declare
declare
a number:=10;
b number:=20;
c number;
begin
c:=a+b;
dbms_output.put_line('Sum of'||a||'and'||b||'is'||c);
end;
/
ex4: Using predefined function in pl/sql block
declare
v_ename varchar2(10):='SMITH';
v_num number;
begin
v_num:=length(v_ename);
dbms_output.put_line(v_num);
end;
/
In the above example we had given the values manually.
to provide the values dynamically we can use '&' operator.
declare
v_ename varchar2(10):='&v_ename';
v_num number;
begin
v_num:=length(v_ename);
dbms_output.put_line(v_num);
end;
/
Commenting In pl/sql:
-> To Comment a single line '--' is used
-> To comment list of lines '/*....*/'
ex1:
declare
v_ename varchar2(10);
begin
select ename into v_ename from emp where empno=7788;
dbms_output.put_line(v_ename);
end;
/
|-----------------------------------------------------------|
|l or L or ; -> to view recently executed code. |
|-----------------------------------------------------------|
ex2:
declare
ename varchar2(10);
sal number;
job varchar2(10);
hiredate date;
begin
select ename,sal,job,hiredate into ename,sal,job,hiredate from emp
where empno=7788;
dbms_output.put_line(ename||' '||sal||' '||job||' '||hiredate);
end;
/
%type:
syntax:
<tablename>.<colname>%type;
Ex1:
declare
v_ename emp.ename%type;
begin
select ename into v_ename from emp where empno=7902;
dbms_output.put_line(v_ename);
end;
/
Ex2:
declare
v_ename emp.ename%type;
v_job emp.job%type;
v_sal emp.sal%type;
v_hiredate emp.hiredate%type;
v_deptno emp.deptno%type;
begin
select ename,job,sal,hiredate,deptno
into v_ename,v_job,v_sal,v_hiredate,v_deptno from emp where
empno=7566;
dbms_output.put_line(v_ename||' '||v_job||' '||v_sal||' '||
v_hiredate||' '||v_deptno);
end;
/
Composite Datatype:
%rowtype:
Is used to hold more than one datatype.
NOTE:
%type and %rowtype are the variable attributes.
Bind variables:
The variables declared outside the pl/sql block.
ex:
sql>>variable a number;
sql>>print <bind_variable_name>;
sql>> var
sql>>begin
select ename,sal,job into :v_ename,:v_sal,:v_job from emp
where empno=7566;
dbms_output.put_line(:v_ename||:v_sal||:v_job);
end;
/
Note:
without using dbms_output we print the bind variable values directly
ex:
begin
execute immediate 'create table sample(sno number)';
execute immediate 'grant select on emp to ora002';
end;
/
CONTROL STRUCTURES
Devided into two types
1. Conditional 2. Iterative Control Structures or loops
ex:
declare
n number:=&n;
begin
if n>=1 then
dbms_output.put_line('positive');
end if;
end;
/
2). If-Else.
Syntax:
if <condition> then
sequence of stmts1;
else
sequence of stmts2;
end if;
/
ex:
declare
n number:=&n;
begin
syntax:
if <condition> then
stmt1;
elsif <condition> then
stmt2;
else
stmt3;
end if;
ex:
declare
n number:=&n;
begin
if n>=1 then
dbms_output.put_line('positive');
elsif n=0 then
dbms_output.put_line('zero');
else
dbms_output.put_line('negative');
end if;
end;
/
ex2:
declare
a number:=&a;
begin
if (a is null) then
dbms_output.put_line('value is null');
else
if(a=0) then
dbms_output.put_line('value is zero');
else
Question:
Increase the employees salary who sal is less than 3000
declare
v_empno number:=&v_empno;
v_sal number;
begin
select sal into v_sal from emp where empno=v_empno;
dbms_output.put_line('old salary is'||v_sal);
if v_sal<3000 then
update emp set sal=sal+200 where empno=v_empno;
commit;
select sal into v_sal from emp where empno=v_empno;
dbms_output.put_line('new salary is'||v_sal);
else
dbms_output.put_line('no updations');
end if;
end;
/
Local Variables & Global Variables:
declare
a number:=10;
begin
dbms_output.put_line(a);
Labled Blocks:
<<b1>>
declare
a number:=10;
begin
dbms_output.put_line(a);
<<b2>>
declare
a number:=20;
begin
dbms_output.put_line(a);
dbms_output.put_line(b1.a);
end b2;
end;
/
Nested Block:
declare
a number:=10;
begin
dbms_output.put_line(a);
declare
b number:=20;
begin
dbms_output.put_line(b);
dbms_output.put_line(a);
end;
dbms_output.put_line(a);
end;
/
Simple Loop:
Syntax:
loop
exit when <condition>
sequence of stmts;
end loop;
Ex:
Print 1 to 5 numbers using simple loop
declare
n number:=1;
begin
loop
exit when n>5
dbms_output.put_line(n);
n:=n+1;
end loop;
end;
/
While Loop:
Syntax:
while <condition>
loop
sequence of stmts;
end loop;
For Loop:
For loop also called as numeric loop.
Syntax:
for loopcounter in lowerbound..upperbound
loop
sequence of stmt;
end loop;
ex:
Print numbers from 1 to 7
begin
for i in 1..7
loop
dbms_output.put_line(i);
end loop;
end;
/
begin
for i in reverse 1..7
loop
dbms_output.put_line(i);
Ex:
Print as below given
*
* *
* * *
* * * *
* * * * *
* * * *
* * *
* *
*
declare
n varchar2(20);
begin
for i in 1..5
loop for j in 1..i
loop
n:=n||'*';
end loop;
dbms_output.put_line(n);
Ex:
Print the output as
---*
--***
-*****
*******
declare
v varchar2(100):='*';
n number:=1;
j number:=3;
a char(200);
spac varchar2(100);
spac_1 number;
begin
loop
exit when n>5;
for k in 1..j
loop
spac:=spac||'-';
end loop;
Cursor Types:
1. implicit cursors -> Managed by oracle
2. Explicit Cursors -> Managed by user
1. Implicit cursors:
Declared for all pl/sql DML, pl/sql select statements.
ex:(for dml)
begin
update emp set sal=sal+200;
delete from emp where deptno=10;
end;
ex: (for select)
declare
n number;
begin
select ename into n from emp where empno=7900;
end;
/
ex1:
begin
delete from emp;
Ex1:
begin
delete from emp;
Explicit Cursors
Declared and named by the programmer and used for select
statements.
Explicit cursors are always defined only on 'select' queries and the select
query may refere any no.of tables.
_________
| |-- ->|--- ---|
|101 abc | |_______|
|102 bcd | |_______|--> Active Set
| | |_______|
| | |_______|
| |
| |--> Actual table
|___________|
Note: The explicit Cursor always points to first record of the o/p.
opening Cursor:
open <cursor_name>;
Fetching:
Fetch <cursor_name> into [(var1,var2,....)/record name];
Closing:
close <cursor_name>;
Ex1:
declare
n number;
cursor c1 is select sal from emp where empno=7788;
begin
open c1;
fetch c1 into n;
dbms_output.put_line(n);
close c1;
end;
/
Ex2:
declare
v_ename varchar2(10);
v_sal number;
declare
cursor c1 is select empno,ename from emp;
Ex6:
declare
cursor c1 is select *from emp;
rec c1%rowtype;
begin
if c1%isopen then
dbms_output.put_line('cursor is opne');
else
dbms_output.put_line('cursor is not open');
open c1;
end if;
loop
declare
cursor c1 is select ename,sal from emp where deptno=10;
v_ename varchar2(10);
v_sal number;
begin
open c1;
loop
fetch c1 into v_ename,v_sal;
exit when c1%notfound;
dbms_output.put_line(v_ename||' '||v_sal);
end loop;
end;
/
CURSOR FOR LOOP
declare
cursor c1 is select *from emp;
begin
for rec in c1
loop
dbms_output.put_line(rec.empno||' '||rec.ename);
end loop;
end;
/
declare
cursor c1 is select ename,sal from emp;
v_ename varchar2(10);
declare
cnt number;
xyz number;
cursor countcur(dno number) is select count(*)from emp where
deptno=dno;
begin
open countcur(10);
fetch countcur into xyz;
dbms_output.put_line(xyz);
close countcur;
open countcur(20);
fetch countcur into xyz;
dbms_output.put_line(xyz);
close countcur;
open countcur(30);
fetch countcur into xyz;
dbms_output.put_line(xyz);
close countcur;
end;
/
declare
cnt number;
INLINE CURSOR
ex:
begin
for i in(select *from emp)
loop
dbms_output.put_line(i.ename||' '||i.job);
end loop;
end;
/
ex2:
Print emp records without cursors.
begin
for i in(select *From emp)
loop
dbms_output.put_line(i.empno||i.ename||i.sal);
end loop;
end;
/
declare
cursor c1 is select *From emp for update;
begin
for rec in c1 loop
dbms_output.put_line(rec.empno||rec.ename);
end loop;
end;
/
|--------------------------- |--------------------------------------
| Implicit Cursors | Explicit Cursors
|--------------------------- |-------------------------------------
|1. controlled by oracle |1. Controlled by user
|2. Defined on DML,Select |2. Only on select queries
| queries |
|3. If the query retrieves 0 |3. Exception is not raised when the
| rows then no_data_found | query retrieves 0 rows
| exception is raised. |
|4. Performance is better than|4. Poor Performance compared to
| explicit cursors | implicit cursors
|5. %rowcount give the no.of |5. %rowcount give the no.of rows
| rows processed by the user| processed by the cursor so far
| ex: 10 | ex: 1,2,3,4......
|6. sql%open always false |6. If the cursor is opened the
| | then it is true other wise it
| | will be false.
|_________________________ |______________________________________
EXCEPTIONS
Ex3:
declare
n number;
begin
delete from emp where deptno=10;
select sal into n from emp where empno=&empno;
dbms_output.put_line(n);
exception
when others then
commit;
end;
/
Types Of exceptions:
Predefined:
The exception which are already derived by oracle
the predefined exceptions will have error message and error number.
DUP_VAL_ON_INDEX ORA-00001 -1
Ex1:
declare
e_notnull exception;
pragma exception_init(e_notnull,-1400);
begin
insert into emp(empno,ename) values(null,'&ename');
commit;
exception
when e_notnull then
dbms_output.put_line('you can not leave a field blank at empno');
end;
Userdefined Exception:
In this user defined exception the user has to define the exception
name
and the error code also.
Ex1:
declare
v_empno emp.empno%type;
begin
select empno into v_empno from emp where
empno=100;
exception
when
no_data_found
then
raise_application_error(-20112,'no records found with matching
empno');
end;
/
Ex2:
declare
i emp%rowtype;
begin
select ename,sal,empno into i.ename,i.sal,i.empno
from emp where empno=&empno;
Error Traping:
declare
msg varchar2(100);
code varchar2(100);
begin
insert into test values(101);
insert into test values(101);
exception
when others then
msg:=substr(sqlerrm,1,100);
code:=sqlcode;
insert into error_msg_log values(code,msg,systimestamp);
commit;
end;
/
PROCEDURES:
Storing a pl/sql block in the database is called stored procedure.
--> procedures will not occupy any space.
Ex:
CREATE OR REPLACE PROCEDURE greetings
AS
BEGIN
dbms_output.put_line('Hello World!');
END;
/
executing the procedure:
exec procedure_name
exec greetings;
Syntax:
create or replace procedure <proc_name>
(parameter1 <mode> datatype,
parameter2 <mode> datatype,
.
.
.
)
is/as
procedure body;
end procedure_name;
Ex2:
create or replace procedure proc_si(p in number,n in number,r in number)
is
si number;
sql>>
declare
a number:=&a;
b number:=&b;
c number:=&c;
begin
proc_si(a,b,c);
end;
/
--IN:
-- If the parameter is in mode then a user can pass a value to
procedure.
--OUT: If the parameter is OUT mode then a user gets a value from the
--- procedure.
--IN OUT:if the parameter is in out mode then a user can pass a value to
the
--- procedure and from the same we can use the parameter to send a
value
to the user.
NOTE: Do not specify any size to datatype.
exec inmode(23,2);
sql>>exec proc4(10);
sql>>
declare
v_num number:=&v_num;
begin
proc4(v_num);
end;
/
Using OUT mode parameter:
create or replace procedure outmode(a number,b number,c out number)
ex2:
create or replace procedure proc3(vdeptno in number,pdname out
varchar2,ploc out varchar2)
as
begin
select dname,loc into pdname,ploc from dept where
deptno=vdeptno;
end;
/
declare
a varchar2(10);
b varchar2(20);
begin
proc3(10,a,b);
dbms_output.put_line(a || b);
end;
/
declare
abc number:=&abc;
begin
inout(200,abc);
dbms_output.put_line(abc);
end;
/
Ex2:
create or replace procedure square(a in out number)
is
begin
a:=a*a;
dbms_output.put_line(a);
end square;
/
declare
b number:=&b;
begin
square(b);
end;
/
positional:
ex:
exec demo_sum(10,20,30);
named:
ex:
exec demo_sum(a=>10,b=>20,c=>30);
combined:
ex:
exec demo_sum(10,20,c=>30);
NOTE: while passing the parameters using combined always the named
parameters should write at last.
Note:
The pl/sql block should have atleast one return statement.
ex:
create or replace function sunfun(a number, b number)
return number
as
begin
return(a+b);
end;
/
Ex:
Create function to print day of given date:
Package specification:
In package specification specifiy only the procedures and functions
along with parameters without any executable sections.
Note:
With out creating a package specification creating package body is not
possible
sql>>exec package_name.element_name;
ex1_specification:
create or replace package new_pack
as
procedure p1(a in number,b in number,c out number);
end;
/
ex1_body:
create or replace package body new_pack
as
procedure p1(a in number,b in number,c out number)
as
begin
c:=a+b;
dbms_output.put_line(c);
end p1;
end new_pack;
/
sql>> declare
a number:=&a;
b number:=&b;
sql>>
declare
code customers.id%type:=&id;
begin
cust_sal.find_sal(code);
end;
/
sql>>exec cust_sal.find_sal(2);
sql>>exec cust_sal.find_sal(1);
create or replace package e_package as
PRAGMA autonomous_transaction;
ex:
create or replace procedure add_emp
as
pragma autonomous_transaction;
begin
insert into emp(empno,ename) values(101,50);
Database Triggers:
Fires when ever a data event (such as DML) or system event(such as
logon or shutdown) occurs on a schema or database.
*. When Clause:
-> Restricting condition
*. Trigger Body
-> Pl/sql Block
Ex:
create or replace trigger intrig before insert on emp
for each row
begin
dbms_output.put_line('While inserting before');
end intrig;
/
Syntax:
:new.<colname>
_____________________________________
| EVENT | OLD | NEW |
|---------- |---------- |---- |
|INSERT | NO | YES |
|UPDATE | YES | YES |
|DELETE | YES | NO |
|--------- |--------- |------ |