Oracle PL-SQL Training Document PDF
Oracle PL-SQL Training Document PDF
Raju Ch
Raju Ch
Raju Ch
3. Blocks
i. Unnamed or anonymous block
ii. Named or stored procedures
iii. Labeled blocks
4. Control statements or control structures
i. Sequential (default)
ii. Conditional (if, case)
5. Cursors
i. Implicit
ii. Explicit
iii. Ref cursor
6. Exceptions (To handle run time errors)
i. predefine
ii. user define
iii. non predefine
7. stored procedure
i. procedures
ii. functions
iii. packages
iv. triggers
8.
9.
10.
11.
12.
13.
14.
15.
pragmas
no copy
forward declaration
bulk collect & bulk bind
mutating triggers
dynamic sql (execute immediate)
table function
advanced topics
This is a procedural language or programming language
It consist of unit blocks
Raju Ch
Raju Ch
Declare
begin
code;
Exception
Optional (Exception Section)
End;
Declarative Section:We use declarative section to define variables, constants, cursors, exceptions, etc.,
We have to define the things in declarative section which are not understand by PL/SQL engine which is
optional?
Excitable Section:Here we define or we provide coding path
Execution takes place in executable section which is mandatory
It starts from begin to end
Exception section:-We use exception section to handle runtime errors and which is optional
Nested Blocks: Block within another block is called nested block
Declare
begin
Declare
begin
Outer block
or
Enclosing Block
code;
Exception
End;
Exception
End;
Inner block
Raju Ch
Begin
Begin
End;
End;
Example:1. Write a program to display the message on to the screen?
begin
dbms_output.put_line('hello welcome to pl/sql');
dbms_output.put_line('this is OracleApps88.Blogspot.com');
end;
Output:-
Begin
NULL;
End;
Begin
o/p not coming w/o using stmt.
End;
2 Using Constant:- We dont change modifications in entire block
DECLARE
A
CONSTANT NUMBER (5, 3) := 3.142;
B
NUMBER (5) := 100;
BEGIN
B := 50;
DBMS_OUTPUT.put_line (a + b);
END;
Output:
Raju Ch
End;
4. Write a program to calculate the area of the circle by knowing the radius
DECLARE
a
NUMBER (5, 3);
r
NUMBER (5) := &n;
p
CONSTANT NUMBER (5, 3) := 3.142;
BEGIN
a := p * POWER (r, 2);
-(or you can use p*r*r)
DBMS_OUTPUT.put_line ('Area of the circle ' || a);
END;
/
Out Put:
Output:-
Raju Ch
Ex:-variable emp.ename%type;
DECLARE
vno
vname
BEGIN
SELECT
INTO
FROM
WHERE
emp.empno%TYPE := &n;
emp.ename%TYPE;
ename
vname
emp
empno = vno;
Output:
emp.empno%TYPE := &n;
emp%ROWTYPE;
*
vrow
emp
empno = vno;
Output:
Disadvantage:- by using %rowtype it is not possible to store table record along with user data or user
information
4. CONTROL STATEMENTS
Control flow
1. if statement
2. case statement
1. If condition:
Ex:DECLARE
v
NUMBER (5) := &n;
BEGIN
IF v > 1000
THEN
DBMS_OUTPUT.put_line ('hellow given number is > 1000');
ELSE
DBMS_OUTPUT.put_line ('number is < 1000');
END IF;
END;
/
Output:-
Case:
1. Simple case
2. Search case
Syntax:
Case [columns/expressions]
When condition then
Do1; (stmts)
When condition then
Do2; (stmts)
Raju Ch
Ex:SELECTSUM(CASE
WHEN sal =5000
THEN sal
WHEN sal >=3000
THEN sal
ELSE sal
END
) sum_sal
FROMemp
Output:
Ex:DECLARE
Raju Ch
Raju Ch
emp.sal%TYPE;
emp.empno%TYPE := &n;
sal
vsal
emp
empno = vno;
CASE
WHEN vsal = 5000
THEN
DBMS_OUTPUT.put_line ('sal = 5000');
WHEN vsal >= 3000
THEN
DBMS_OUTPUT.put_line ('sal = 3000');
ELSE
DBMS_OUTPUT.put_line ('sal < 3000');
END CASE;
END;
/
Output:
Note:- In the absence of else part if all of the conditions are false then it throws on an error i.e. case not found.
(it throws err ORA-06592, pls check below o/p)
Ex:DECLARE
vsal
vno
BEGIN
SELECT
INTO
FROM
WHERE
emp.sal%TYPE;
emp.empno%TYPE := &n;
sal
vsal
emp
empno = vno;
CASE
WHEN vsal > 5000
THEN
DBMS_OUTPUT.put_line ('sal = 5000');
WHEN vsal > 6000
THEN
DBMS_OUTPUT.put_line ('sal = 6000');
END CASE;
END;
/
Output:
emp.sal%TYPE;
emp.empno%TYPE := &n;
sal
vsal
emp
empno = vno;
CASE vsal
WHEN 5000
THEN
DBMS_OUTPUT.put_line ('sal = 5000');
WHEN 3000
THEN
DBMS_OUTPUT.put_line ('sal = 3000');
ELSE
DBMS_OUTPUT.put_line ('sal < 3000');
END CASE;
END;
/
Output:
1.
2.
3.
a.
b.
1.
c) Iterations:
Loops:- to execute the same statement or coding for repeated times we use loops
Simple loop
While loop
for loop
Numeric for loop
Cursor for loop
Simple loop:- it is an infinite loop explicitly we have to stop the loop. It is uses in blocks.
Syntax:Loop
Code;
End loop;
Raju Ch
Output:
Raju Ch
Raju Ch
Raju Ch
Ex:DECLARE
x
NUMBER (5) := 1;
y
NUMBER (5) := 1;
BEGIN
LOOP
y := 1;
LOOP
DBMS_OUTPUT.put_line (x || '*' || y || '=' || x * y);
y := y + 1;
EXIT WHEN y > 10;
END LOOP;
x := x + 1;
EXIT WHEN x > 10;
END LOOP;
END;
/
Output:
Write a program to reverse the give string by using simple loop (without using reverse function)
For loop:
Syntax:
For var in [reverse] val1..val2 loop
Code;
End;
Ex:-Begin
For I in 1..10 loop
Dbms_output.put_line(i);
End loop;
End;
Ex:Begin
For I in reverse 1..10 loop
Dbms_output.put_line(i);
End loop;
Raju Ch
Raju Ch
CURSORES
Oracle will make use of internal memory areas (implicit cursors) for sql statements to process the records
This memory areas will be defined in a area called SGA (system global area)
Oracle allows to provide our own memory areas (explicit cursors) to get control over each of the record
Definition:-It is a pointer pointing towards the arranged data in a context area
In explicit cursors user has to declare, open, fetch and close the cursors. Whereas in the case of impolicit
cursors system has to look after all this functionalities.
Cursor functionalities:
Step 1: Declaring the cursor
Syntax:-cursor cursor_name is select
Step 2:opening a cursor
Syntax: open cursor_name
Step 3: Fetching records into variable from cursor
Syntax: fetch cursor_name into variable;
Step 4: closing cursor
Syntax: close cursor_name
1.
2.
3.
4.
5.
6.
Cursor Attributes
Cursor_name%isopen;
Cursor_name%found;
Cursor_name%notfound;
Cursor_name%rowcount;
Cursor_name%bulk_rowcount;
Cursor_name%bulk_exception; (save exception 11g)
Cursor_name%isopen: returns true if cursor is opened else false
Cursor_name%found: returns true if records are found else false
Cursor_name%notfound: reverse to the found
Cursor_name%rowcount: returns number of records fetched to that state
Example for explicit cursor:
Declare
Cursor c is select ename for emp;
Vname c%rowtype;
Begin
Open c;
Loop
Fetch c into vname;
Exit when c%not found;
Dbms_output.put_line(vname.ename);
End loop;
End;
Ex: Declare
Cursor c is select ename for emp;
Vname emp.ename%type;
Begin
Open c;
Raju Ch
Loop
Fetch c into vname;
Exit when c%notfound;
Dbms_output.put_line(vname);
End loop;
Close c;
End;
Cursor
event
Open cursor
1ST FETCH
2ND FETCH
(FETCHES)
LAST
FETCH
CLOSE
CURSOR
%isopen
%found
%notfound
%rowcount
Before
AFTER
BEFORE
AFTER
BEFORE
F
T
T
T
T
E
N
N
T
T
E
N
N
F
F
E
O
O
I
I
AFTER
BEFORE
T
T
T
T
F
F
DD
DD
AFTER
BEFORE
T
T
F
F
T
T
DD
DD
AFTER
F
E
E
E
E -> Exceptions
DD -> data dependence
In for loops no need to open fetch and close the cursors. It happens through for loop
For loop cursors:
DECLARE
CURSOR c
IS
SELECT ename from emp;
begin
for I in c loop
dbms_output.put_line(i.ename);
end loop;
end;
Parameterised Cursors:
In cursors we use In parameters
Ex:
Declare
Cursor c(x emp.deptno%type) is select ename from emp where deptno = x;
Vname emp.ename%type;
Vno number(5):=&n;
Begin
Open c(vno);
Loop
Fetch c into vname;
Exit when c%notfound;
Dbms_output.put_line(vname);
End loop;
Close c;
Raju Ch
Raju Ch
Declare
Type rec is refcursor;
Vrec rec;
Vemp emp.ename%type;
Vdept dept.loc%type;
Begin
Open vrec for select ename from emp;
Loop
Fetch vrec into vemp;
Exit when vrec%notfound;
Dbms_output.put_line(vemp);
End loop;
Close vrec;
Dbms_output.put_line(++++++++);
Open vrec for select dname from dept;
Loop
Fetch vrec into vdept;
Exit when vrec%notfound;
Dbms_output.put_line(vdept);
End loop;
Close vrec;
End;
1.
2.
Raju Ch
1.
2.
Cursor expressions:
EXCEPTIONS
Basically or generally errors are of two types
Syntactical
Runtime
We will get syntactical errors ar compilation time they itself we can rectify the compilation errors
To handle the runtime errors we use exceptions
Types of exceptions
User defined
Pre-defined
Non predefined
In user defined exceptions user has to declared the exceptions, raise and the handle the exceptions
We handle the errors in exception section by using exception handlers
Whereas in the case of predefined manufacturer as to define system has to raise and user as to handle
Syntax
Declare
Exceptioname exception;
Begin
Raise exceptionname;
Exception
When exceptionname then
When
Exception then
End;
Predefined Exceptions
Ex:Declare
Vno emp.empno%type :=&n;
Vname emp.ename%type;
Begin
Select ename into vname from emp where empno = vno;
Dbms_output.put_line(hello);
Exception
When too_many_rows then
Raju Ch
Exception name
100
-1422
-6592
-1722
-6502
-6511
-1001
-1476
-0001
-6531
-6533
-6532
-6501
-6500
-1017
-30625
-6504
-6548
User_defined exceptions:
Declare
Ex exception;
Vno emp.empno%type :=&n;
Vrow emp%rowtype;
Begin
Select * into vrow from emp where empno = vno;
If vrow.comm is null then
CASES IN EXCEPTIONS OR EXCEPTIONAL CASES
CASE: 1
DECLARE
----------------;
BEGIN
----------------;
EXCEPTION
WHEN OTHERS THEN;
----------------------------------;
WHEN EX THEN;
---------------------------------;
Raju Ch
END;
NOTE: It throws an error. Others should not be at first in the list of exceptions. It should be always at last
among exceptions.
CASE: 2
DECLARE
----------------;
BEGIN
----------------;
EXCEPTION
WHEN EX1 OR EX2 THEN;
---------------------------------------;
END;
NOTE: It is possible to mention the exception in series by separating with OR operator.
CASE: 3
DECLARE
------------BEGIN
------------EXCEPTION
WHEN EX1 OR OTHERS THEN;
----------------------------------------------END;
NOTE: It is not possible to mention the exception in series by separating withOR operator.
CASE: 4
DECLARE
----------------;
BEGIN
----------------;
EXCEPTION
WHEN EX1 AND EX2 THEN;
------------------------------------------;
END;
NOTE: It is not possible to mention the exception in series by separating
with AND operator.
CASE: 5
DECLARE
-----------------BEGIN
BEGIN
RAISE EX;
EXCEPTION;
WHEN EX2 THEN;
END;
EXCEPTION
WHEN EX THEN;
Raju Ch
END;
NOTE: Exceptions raised in inner block can be handled in the outer
block. This is called as EXCEPTION PROPAGATION.
CASE:6
DECLARE
---------------;
BEGIN
RAISE EX2;
BEGIN
RAISE EX;
EXCEPTION
WHEN EX2 THEN;
END;
EXCEPTION
WHEN EX THEN;
END;
NOTE: Exception raised in outer block cannot be handled in inner block.
CASE: 7
DECLARE
---------------BEGIN
BEGIN
RAISE EX
EXCEPTION
WHEN EX THEN;
-------------------------RAISE
WHEN EX THEN;
-----------------------;
END;
EXCEPTION
WHEN EX THEN;
-------------------------;
END;
NOTE: Exception raised in exception section cannot be handled in the same block exceptional section. But
possible to handle outer bock exceptional sections which is also called as EXCEPTION PROPAGATION
CASE: 8
DECLARE
--------------BEGIN
DECLARE
V NUMBER (2):=12345
BEGIN
---------------EXCEPTION
Raju Ch
NOTE:
If we get only 'H' as output then in first select statement the exception has occurred.
If we get 'H','A' as output then in second select statement the exception has occurred.
If we get 'H' ,'A','R' as output then in third select statement the exception has occurred.
If we get 'H' ,'A','R','I' as output then in fourth select statement the exception has occurred.
If we get 'H' ,'A','R' ,I','S' as output then in third select statement the exception has occurred.
If we get 'H' ,'A','R','S',H' as output then there are no error in select statements.
1.
2.
1)
2)
3)
4)
i.
ii.
iii.
iv.
v.
vi.
vii.
viii.
ix.
1)
2)
3)
4)
5)
6)
Raju Ch
Calling procedure:SQL/Plus
SQL developer(new tool)
Blocks
Unix
Front end applications(apps)
Web applications
Raju Ch
Declare
vname varchar2(10):=&n;
a number(5);
begin
select sal into a from emp where ename=vname;
p(a);
end;
create or replace procdure p(X number, Y number) is vname varchar2(10);
begin
select ename into vname from emp where empno=X and sal=Y;
DBMS_OUTPUT.PUT_LINE(employee name||vname);
end;/
-procedure created.
declare
Vno number (5):=&n;
Vsal number (5):=&m;
begin
p(vno,vsal);
end;
SQL/Plus:- Calling environment
var a number;
var b number;
exec :a:=7839;
exec :b:=5000;
exec p(:a,:b);
procedure with OUT parameters:Create or replace procedure p(X in number,Y out varchar) is
begin
select ename into Y from emp where empno=x;
end;
Raju Ch
Raju Ch
SQL/Plus:var a number;
var b varchar2(10);
exec :a:=7839;
exec p(:a,:b);
print b;
exec DOCL(:b);
blocks:declare
a number(5):=7839;
b varchar2(10);
begin
p(a,b);
DOCL(b);
end;
Spool concept:Sql>spool c:/gv.sql;
>select * from emp;
Sql>spool off;
Sql>spool c:/gv.sql append ; (it will append to previous one)
>
While creating time we will declare (arguments/parameters eg: X in number) we will call that as formal
parameters.
EX: exec p(:a,:b) these are actual parameters.
We will refer the values from actual to formal in three notations:
1. Positional notation; (based on position value will be referred).
Raju Ch
2. Named notation; (by using names (formal parameters) we can implies the value)
3. Mixed notation.
i.
ii.
SQL*Plus:Var a number;
Var b number;
Exec :a:=100;
Exec p(:a, :b);
Print b;
Once we pass the value to In parameter throughout the program we cant vary the value.
Note:- Always In parameters should not be at left side of assignment operator which means In parameters
acts as a constant in the scope of program.
Create or replace procedure p(X in number, Y out number) is
Raju Ch
Begin
X:=200;
Y:=X+100;
End;
Exec p(100,:b)
Local subprograms: They are procedures/functions which are defined in the declarative section named and unnamed blocks.
We have to call these local programs within the scope of that block.
It wont get stored anywhere else on by themselves.
Declare
Procedure p is
Begin
local sub programs
DOCL(hello);
End p;
Begin p;
End; Here we wont mention create/replace.
Declarative section we will handle these 8: Variables, exceptions, cursors, constants, data types, programs, defining local programs.
Forward declaration:Basically if you want to call a program it has to be get defined very previously.
Whenever you call a program before defining throws an error.
For mutual exchange purpose sometimes we have a need to call a procedure before defining.
To fulfill this requirement we will declare the procedure very previously which is calling before defining.
If you want to call a procedure before defining you have to declare those procedures vary previously.
Declare
V number (5):=5;
Procedure p2(Y inout number);
--forward declaration
Procedure p1(X inout number) is
Begin
If X>0 then
Docl(X);
X:=X-1;
P2(X);--calling
End if;
End p1;
Procedure p2(Y inout number) is --defining
Begin
P1(Y);
End p2;
Begin
P2(v); -- calling and executable section first compiler comes here.
First define then call any procedure without defining if
you need to make a call at least we need to declare.
End;
Raju Ch
End p3;
Exec p3;
Note: A procedure can optionally contain return statement but it wont through any value as in the given eg.
Create or replace procedure p3 is
V number(5):=100;
Begin
DOCL(v);
Return v;
DBMS_OUTPUT.PUT_LINE(v);
End p3;
Functions
They are the PL/SQL program units which allow parameters similar to that of procedures.
But unlike procedures they return value by default.
Functions are useful for calculation purpose and for data manipulation purpose (DML).
Functions makes the queries simple, readable and also enhance the performance.
Note:- Providing out and inout parameters in functions is not preferable.
Syntax:- create or replace function <function_name> (Para) return datatype
[pipelined|aggregate|parallelenabled|deterministic|authiduser] is/as
Begin
Code;
Return statement;
Exception
----------End[procedure name];
1.
2.
3.
4.
5.
6.
Calling functions:SQL/Plus
Blocks
SQl Developer
Apps
Select statement
Objects
Functions without any parameter:create or replace function fun return number is
v number(5):=&n;
begin
return v; -- we can give assign value/exp/literals/collections.
end;
block:declare
a number(5);
begin
a:= fun;
DBMS_OUTPUT.PUT_LINE(a);
Raju Ch
End;
SQL/Plus:Var a number;
Exec :a:=fun; --where a holds the value
Print a;
Create or replace procedure p is
B number(5);
Begin
B:=fun;
DBMS_OUTPUT.PUT_LINE(b);
End p;
Create or replace function f1 return number is
Begin
Return fun;
End f1;
Select fun from dual;
Note:- In the return statement we can mention value directly, expression, another function, cursor variables,
index by table (collection), Boolean value, and so on..
Function with IN parameter:Create or replace function fin(X number) return variable is Vname emp.ename%type;
Begin
Select ename into vname from emp where empno:=X;
End fin;
SQL/Plus:Var a carchar2(10);
Var b number;
Exec :b:=7788;
Exec :a:=fin(:b);
Print a;
Blocks:Declare
A varchar2(10);
B number(5):=&n;
Begin
A:=fin(b);
DBMS_OUTPUT.PUT_LINE(a);
End;
Select fin(empno) from emp;
Create or replace function fn(X varchar2) return number is Vno number(5);
Begin
Select empno into vno from emp where ename=X;
Return vno;
End fn;
Raju Ch
o
o
Using multiple return statements in functions:Create or replace function f(X number) return number is v number(5):=1000;
Begin
If x>100 then
Return(x);
Else
Return v;
End if;
End;
Create or replace function f return.
Begin
Return X;
Return Y;
End;
If control looks first return statement the control automatically comes out of function them it wont goes to
second return statement.
DBMS_OUTPUT.PUT_LINE wont supportsT(or) F
SQL*Plus:Var a number;
Exec :a:=F(500);
Print a;
Function without parameters:Returning Boolean value from the function:Create or replace function f return Boolean is v number(5):=100;
Begin
Return null;
End;
Blocks:Declare
A Boolean;
Begin
A:=f;
DOCL(value ||a);
End;
SQL wont supports Boolean datatype.
EX for out:Create or replace function f(X out number) return number is v number(5):=100;
Begin
X:=v+500;
Return v;
End;
SQL*Plus:var a number;
var b number;
Raju Ch
exec :a:=f(:b);
print a;
100
Print b;
600
Blocks:Declare
A nmber(5);
B number(5);
Begin
A:=f(b);
DBMS_OUTPUT.PUT_LINE(a|| ||b);
End;
SQL> select f(:b) from dual;
Note: It is not possible to call the function which are having out and in out parameters in select statement.
Function with inout parameter:Create or replace function f(X inout number) return number is v umber(5):=100;
Begin
X: =v+500+X;
Return v;
End;
SQL*Plus:Var a number;
Var b number;
Exec: b: =500;
Exec: a: =f (: b);
Print a;
Print b;
Blocks:Declare
A number (5);
B number (5);
Begin
A: =f (b);
DBMS_OUTPUT.PUT_LINE (a|| ||b);
End;
i.
ii.
iii.
iv.
v.
vi.
vii.
viii.
Raju Ch
DML statements
Commit
DML
Selec
t
Rollback to save
point
DML
Select
Alter system
Alter session
In the above diagram select statements DML is not possibls and select is possible.
In the DML statements DML will not possible on same function table. But it will possible on different function
tables.
In DML statements select possible on different (or) same function table.
Raju Ch
Var a number;
Exec :a:=f;
--throws an error.
Diff between procedure and function:Procedure: Procedure may (or) may not return a value.
Not passable to call in SQL statements.
It acts as a PL/SQL statement execution (for statements execution purpose).
Forward declaration:Basically if you want to call a program it has to be get defined very previously.
Whenever you call a program before defining throws an error.
For mutual exchange purpose sometimes we have a need to call a procedure before defining.
To fulfill this requirement we will declare the procedure very previously which is calling before defining.
If you want to call a procedure before defining you have to declare those procedures vary previously.
Declare
V number (5):=5;
Procedure p2(Y input number);
--forward declaration
Procedure p1(X input number) is
Begin
If X>0 then
Docl(X)
X: =X-1;
P2(X); --calling
End if;
End p1;
Procedure p2(Y input number) is --defining
Begin
P1(Y);
End p2;
Begin
P2 (v); -- calling and executable section first compiler comes here.
First define then call any procedure without defining if You need to make a call at least we need to declare.
End;
Create or replace procedure p3 is
(1)
End p3;
Exec p3;
Note:A procedure can optionally contain return statement but it wont through any value as in the given eg.
Create or replace procedure p3 is V number(5):=100;
Begin
Raju Ch
DOCL(v);
Return v;
DBMS_OUTPUT.PUT_LINE(v);
End p3;
Diff between procedure and function:Procedure:Procedure may (or) may not returns a value.
Not passable to call in SQL statements.
It acts as a PL/SQL statement execution(for statements execution purpose).
Packages:It is a container/program unit area which is useful to store related things at one place.
It provides modularity, scalability, encapsulation, data security, portability, code analysation, debugging the
code, tracing the code, profiling the code, location monitoring and so on
Alters/decreases the redundancy.
Note:Packages wont allow parameters, nesting, and calling.
Raju Ch
End packagename;
Raju Ch
Out put:
12
Note:-We avoiding mutating error using pragma.atonomous_transaction.
Packages:It is a container/program unit area which is useful to store related things at one place.
It provides modularity, scalability, encapsulation, data security, portability, code analysation, debugging the
code, tracing the code, profiling the code, location monitoring and so on
Alters/decreases the redundancy.
Note:Packages wont allow parameters, nesting, and calling.
Some built-in packages:Dbms-lob-handles lob related values
Raju Ch
Raju Ch
Raju Ch
FUNCTIONS:
SQL*PLUS
Var a number;
Var b number;
Exec :b:=4000;
Exec :a:=pack.f(:b);
BLOCKS:
Declare
A number(5);
B number(5):=1000;
Begin
A:=pack.f(:b);
DBMS_OUTPUT.PUT_LINE(a|| ||b);
End;
Example for Packaged Crusors:
declare
vrow emp%rowtype;
begin
open pack.c;
loop
fetch pack.c into vrow;
DBMS_OUTPUT.PUT_LINE(vrow.ename);
If vrow.ename=scott then
Raise pack.ex;
End if;
End loop;
Exception
When pack.ex then
DBMS_OUTPUT.PUT_LINE(packex)
End;
Declare
Vrow emp%rowtype;
Begin
Fetch pack.c into vrow;
DBMS_OUTPUT.PUT_LINE(vrow.ename);
End;
OutPut: Ford
NOTE:If you wont close the packaged (packs) cursor in any program then that is last for entire session.
We can call the packaged procedures and functions outside of package which are specified in package
specification(global accessing).
Attempting to call packaged local sub programs to call outside of package throws an error.
Using cursor variable as a parameter value:
Create or replace package pack is type rec is ref cursor;
Procedure p(X rec);
End pack;
Raju Ch
Create or replace package body pack is Procedure p(X rec)is vrow emp%rowtype;
Begin
Loop
Fetch X into vrow ;
DBMS_OUTPUT.PUT_LINE(vrow.ename);
Exit when X%not found;
End loop;
End p;
End pack;
BLOCK:
Declare
Type recl is ref cursor;
Vrec recl;
Begin
Open vrec for select * from emp;
Pack.p(vrec); --calling
End;
Note: Defining cursor variable in package specification will not be allowed but defining ref cursor is possible.
We can use cursor variable as an out parameter:
Create or replace package p(X out sys_refcursor) is vrec sys_refcursor;
Begin
Open vrec for select * from emp;
X:=vrec;
End p;
SQL*PLUS:
Var v refcursor;
Exec p(:v);
Using cursor variable in return statement of a function:
Create or replace function f return sys_refcursor is vrec sys_refcursor;
Begin
Open vrec for select * from emp,dept;
Return vrec;
End f;
Exec :v:=f;
Print v;
Note:If procedure and functions is present in specification then we go for package body otherwise no need.
Packaged Cursors:
Create or replace package pack is cursor c return emp%rowtype is select * from emp;
End pack;
Here we are defining cursor in package specification we can use this anywhere.
Begin
For i in pack.c
Loop
DBMS_OUTPUT.PUT_LINE(i.ename);
End loop ;
Raju Ch
End;
We can hide the cursor select statement through package concept as shown in the snippent:
Create or replace package pack is cursor c return emp%rowtype ;
End pack;
Create or replace package body pack is cursor c return emp%rowtype is select * from emp;
End pack;
Begin
For i in pack.c
Loop
DBMS_OUTPUT.PUT_LINE(i.ename);
End loop ;
End;
Out Put:
Emp 14 records
A package body can optionally contain executable section. Which is one time initialization but it should be at
last in the package body if we have any sub programs.
Create or replace package pack is v number (5);
End pack;
Create or replace package body pack is
Begin
V: =5000;
End pack;
Note:We can also call the packaged function in select statement but that should not contain out and inout
parameter.
Drop package <package_name>
Here along with package specification, body alo will drop.
Dropping packaged body without dropping package specification
Drop package body pack;
Polymorphism(overloading): Defining multiple local subprograms with the very same name but by differing number, order and data types
of parameters.
Create or replace package pack is Procedure p(x number);
Procedure p (x number, y number);
Procedure P(x number, y varchar2);
Procedure p(y varchar2, x number);
End pack;
Note:-The data types should not be same family while comparing to procedures.
Creating or replace package body pack is procedure p(x number) is
Begin
DBMS_OUTPUT.PUT_LINE(x);
End p;
Procedure p(x nmber, y number) is
Begin
DBMS_OUTPUT.PUT_LINE(x||y);
Raju Ch
End p;
Procedure p(x number, y varchar2) is
Begin DBMS_OUTPUT.PUT_LINE(x|| ||y);
End p;
Procedure p(y varchar2, x number)is
Begin
DBMS_OUTPUT.PUT_LINE(y|| ||x);
End p;
End;
Calling environment:SQL>exec p(100);
SQL>exec p(a,200);
SQL>exec p(200,a);
Note:-Overloading is not possible for standard alone program(schema level programs).
V$parameter=>all DB related parameters will store
PL/SQL-optimize-level-initialization parameter.
Where level-0-ideal
Level-1
Level-2-preferrable
Level-3(11g)-aggressive much more faster.
Tuning the PL/SQL code:- optimizing the PL/SQL code:We will tune the PL/SQL code based on initialisation parameter i.e PL/SQL-optimize-level in this we will set
the levels from 0 to 3. Level 2 is default which allows us
1. In lining (11g) a program.
2. Avoiding the in lining program.
Level 0 and 1 wont allow us to in lining program.
Level 3 wont allow us to inline a program but allow us to avoid in lining program.
Declare
Sdate number:=0;
Edate number:=0;
D_code number:=0;
--dead code no use in program
L_r number:=0;
Function f(x number) return number is
Begin
Return x;
End f;
Begin
Sdate:=dbms_utility.get_time; --here we are assigning to one variable
so call it as function.
For I in 1..1000000
Loop
D_code:=0;
--calling
End loop;
Edate:=dbms_utility.get_time;
DBMS_OUTPUT.PUT_LINE(edate_sdate);
End;
Raju Ch
Raju Ch
Understanding the NOTNULL constraint for a PL/SQL variable:Providing NOT NULL constraint for a PL/SQL variable is not preferable doing so, will degrades the
performance because nullity will be checked through one virtual variable created implicitly by the engine.
Declare
Sdate number:=0;
Edate number:=0;
V number not null:=0
Begin
Sdate:=dbms_utility.get_time;
For i in 1..100000000 loop
V:=I;
End loop;
Edate:=dbms_utility.get_time;
DBMS_OUTPUT.PUT_LINE(edate_sdate);
End;
Output:
Time :- 72 minutes.
Note: Internally it takes one virtual variable and it checks v number NOT NULL(it is not preferable more time
it will take if you use coading in program it is better like if v is not null).
Same as above program but variable using without NOTNULL.
Output:
Time: 44
Using pls integer is preferiable than the number since it is faster:V pls_integer:=0;
--we use these only in PL/SQL and remaining is same as above.
Time:-12
Using simple integer is more refereable than pls_integer:Simple integer is a derivate of pls_integer , but avoids overflow error and allow null values.
Note: Up to 10g every datatype allows null values but n 11g simple integer wont allow null value.
Pls_integer size -2147483648 to 2147483647
Note: Pls_integer can store max of 2147483647, if you assign above of this value throws an error i.e overflow
error, to overcome this error we have a datatype called simple-integer(11g) and even simple integer wont
allow null values (NOTNULL datatype) .
Declare
V pls_integer:=214783646;
Begin
V:=v+1;
DBMS_OUTPUT.PUT_LINE(v);
V:=v+1;
DBMS_OUTPUT.PUT_LINE(v);
End;
Out put: Numeric overflow error.
To overcome this
Declare
V simple_integer:=2147483646;
Begin
V:=v+1;
DBMS_OUTPUT.PUT_LINE(v);
Raju Ch
V:=v+1;
DBMS_OUTPUT.PUT_LINE(v);
End;
Out put:
2147483647
-2147483648
Pragmaautonomoustransaction (Tx):It is an independent Tx happens individually irrespective of parent Tx.
Limitations:Package specification wont allow pragma; we can apply for packeged procedures and packages.
Create or replace procedure p is pragma autonomous_transaction;
Begin
Insert into nestab values(10);
End p;
Create table nestab(sno number(5));
Select * form nestab;
Calling environment:
Begin
Insert into nstab values(11);
P;
Insert into nestab values(12);
Rollback;
End;
Output: 10
Raju Ch
LOB datatype:
Before of 8i if you want to store the images or huge information we opt(choose) for long datatypes but , we
have so many restrictions on long datatypes to overcome this disadvantage we have LOB datatype.
Cliassifications of LOB datatype:LOB datatypes can be devided as below:
Internal
Persistance
Non-persistence(temporary)
BLOB
Raju Ch
CLOB
NCLOB
External
Bfiles
CLOB: allows huge information upto 4GB from 11g onwords even it supports 8 to 128TB.
BLOB: stores binary data, allows images, audio,video files and so on
NCLOB: it stores national database chracterset data. Supports multi languages.
Bfiles: useful to store files in the form of binary data.
Commit and rollback is not passible to provide on this data.
abc
1*2
01010
C1CLOB
c2BLOB
CLOB locater
BLOB locator
abc
c3Bfile
Bfile locator
01010
File not store in db
Db
Raju Ch
Dbms_lob.close(vclob);
DBMS_OUTPUT.PUT_LINE(rdata);
End;
Raju Ch
We cant call trigger and pass parameters and cant nest (trigger with in trigger).
Usages: Data auditing
Enforcing the referential integrity
Security
Data replication
Application monitoring(AM)
Enforcing the data
Triggers have their own name space.
Triggers wont allow commit and rollback, but by using pragma atonomous transaction we can mention
commit and rollback in triggers.
Basically triggers are of two types
1.Application trigger
2.Database triggers
1.
2.
3.
4.
5.
1.)
2.)
Statement level trigger:This trigger executes only once for an entire table/for bunch of records execution of this trigger takes place
atleast once. Even if table data wont get effected.
Rowlevel trigger:this trigger executes for each of row.
This trigger wont get executes atleast once if table data wont get effected.
Syntax of DML trigger:Create
or
replace
trigger
<trigger_name>
(1)before/after
DML
operations
on
<table_name>[disable/enable](2)[foreach row](3)[when condition][declare]
Begin
Code;
Exception
End;
(1)-trigger timing:It specifies when trigger has to fire.
(2)-trigger level:Specifies what ever row level/statement level.if you mention for row i.e rowlevel else statement level but
bydefault statement level.
(3)-trigger condition:-(not preferrable)
Raju Ch
If further provides the additional restriction on trigger execution.in trigger conditon should always be a
boolean expression statement level trigger wont allow trigger condition.
(4)-trigger body:It specifies what action we have to perform through trigger.
Ex for statement level trigger:Write a statement level trigger so not tto allow any DML operation on a table on weekends.
Create table stab(sno number(5))
delete
new
null
Here we wil represent new and old in this program i.e rowlevel trigger program.
Write a rowlevel trigger to update the salaries witch one specific value for an increment, if Any one of the
existing salaries is greater than new salaries then I have to cancel all the transactions happened by trigger.
Create or replace trigger ustrig before update on emp1;
For each row
Begin
If :old.sal>:new.sal then
Raise_application_error(-20003,sal cannot be decremented);
Else
DBMS_OUTPUT.PUT_LINE(icremented);end if;
End;
From the trigger if we get any error, all the previous transactions will get cancelled.
Eg for trigger when condition:-
Raju Ch
When condition skips the execution of trigger body when when condition becomes false.(but insertion
takes place).
If when condition becomes true then allows trigger body to execute.
Create or replace trigger logtrig before insert or update or delete on logtab;
For each row
when(to_char(sysdate,HH)not between 05 and 08)
begin
DBMS_OUTPUT.PUT_LINE(login time);
End;
Insert into logtab values(10);
1 row created.
Create table logtab(sno number(5));
Using :new and :old in when condition:Create or replace trigger emp1trig before insert or update or delete on emp1;
For each row
When(new.sal<old.sal)
Begin
DBMS_OUTPUT.PUT_LINE(oldsal<newsal);
End;
In when condition we wont use :new and :old but in trigger body we can use, if you use also it throws an
error.
Update emp1 set sal=4000;
Note: Trigger when condition wont allows colons( to refer old and new values.
Enforcing referential integrity: Triggers cant chek the old/existing data, it checks only incoming data but where as in the case of constraints
they check both incoming and existing data.
Constraints can give guarantee for centralized data.
Triggers are an advance of constraints.
Create trigger contrig after insert on ltab;
For each row
Begin
Insert into ptab values(:new.sno);
End;
Insert into ltab values(11);
Before of constraint checking trigger execution takes place.
Order of execution:
DDL triggers:Syntax:
Create or replace trigger <trigger_name> before/after DDL on schema
Begin
Raju Ch
.
Exception
End [trigger_name]
We write DDL on schema level(insert, update, delete).
DDL attributes:_
In DDL we have more than 100 attributes but here we will go for
Ora_sysevent
Ora_DICT_obj_name
Ora_DICT_obj_type
We will provide DDL commands on schema, mainly for auditing purpose.
Create trigger audtrig before create or drop on schema
Begin
Insert into audtab values (user, ora_sysevent, ora_dict_obj_name, ora_dict_obj_type, sysdate);
End audtrig;
Create table audtab(suser varchar2(10), sevent varchar2(10), sname varchar2(10), stype varchar2(10), sdate
date);
Create table SAM(sno number(5));
Select * from audtab;
Suser
Sevent
Sname
Stype
Sdate
Apps
Create
Sam
Table
11-mar-13
Drop table sam;
Select * from audtab;
We will write DB triggers on below mentioned:Before
Log on
Befor(T)
Log off
Before(T)
Shutdown
Servererror
before
Startup
After(T)
After
After
errornumber
After(T)
Attaching the procedure to the trigger in the place of trigger body with call statement, so to reduce the
redundancy as in the following eg.
Create or replace procedure p is
Begin
DBMS_OUTPUT.PUT_LINE(hello);
End;
Create table RAM(sno number(5));
Create or replace trigger protrig before insert on RAM
Call p(dont use semicolon here, if you use you will get error)
/
Raju Ch
-trigger created.
Insert into RAM values(10);
Hello
-1 row created.
Advanced topics in triggersintroduced from 11g)
It follows reserved word or keywords followed by 11g.
Oracle wont give gurantee for the order of trigger execution among the sametypes but, by using follows(11g)
we can order the execution of triggers.
Create table RAM(sno number(5));
Create or replace trigger trig1 before insert on RAM
Begin
DBMS_OUTPUT.PUT_LINE(trig1);
End trig1;
Create trigger trig2 before insert on RAM follows trig1
Begin
DBMS_OUTPUT.PUT_LINE(trig2);
End trig2;
Output:Trig1
Trig2
Note:If we did not use follows we get out put like
Trig2
Trig1
Oracle wont wives guarantee for order of execution, so from 11g onwords we use follows.
Disable(11g):Prior to 11g we only have an option to disable an existing trigger fron 11g onwords we can disable a trigger
while creating/defining.
Create or replace trigger disable before insert on RAM disable
Begin
DBMS_OUTPUT.PUT_LINE(this is disable trigger);
End disable;
Insert into RAM values(10);
-1 row created.
To enable/disable the trigger weve to make use of ALTER.
Alter trigger distrig enable;
Insert into RAM values(10); --this is disable trigger.
-1 row created.
We can define max of 12 triggers on a table(DML).
We can write a trigger to fire when updating on specific column:Create table uptab(sno number(5), loc varchar2(10));
Create trigger updating before updating of sno on uptab
Begin
DBMS_OUTPUT.PUT_LINE(updating on column);
End;
Insert into uptabvalues(10, x);
Raju Ch
Raju Ch
collection variable should not be NULL, to avoid that in that case we will define elements.
The function should be empty nes()(or)nes(A,B,C,D);
Usage of collections:-
Raju Ch
Raju Ch
1
2
3
4
5
A
B
C
C
D
densely
Raju Ch
Declare
Type nes is table of varchar2(10) index by pls_integer;
Vnes nes:=nes();
Begin
Null;
End;
Error:no function name nes exists in this scope.
NESTED TABLE
First, Last, Next, prior,
count
Limit,
Delete,
Extend,
Trim,
Persistence,
Subscript values,
Usage SQL/PL SQL,
Dense & paye,
Exception,
Storage
Persistence
Always +ve
values,start with 1
SQL & PL/SQL
Initially dense but
may be sparse
Out of line storage.
VARRAYS
Limit (exits upper bound)
Specific deletion is not
possible
Possible within the maxlimit
Persistence
Same as nested table..
SQL & PL/SQL
DENSE
INDEX BY TABLE
LIMIT LESS
Non-Persistance
Might be with ve,
allows caharacterstics
Both
INLINE
Bulk bind:Concept of bulk bind is a mechanism which is used to enhance the performance drastically, by decreasing the
context switches.
Bulk bind reduces the interaction between SQLand PL/SQL engine.
We will maintain the bulk bind data through collections.
Raju Ch
Raju Ch
Open c;
Sdate:=dbms_utility.get_time;
Loop
Vnes.extend;
Fetch c into vnes(vnes.last);
Exit when c%not found;
End loop;
Close c;
Edate:=dbms_utility.get_time;
DBMS_OUTPUT.PUT_LINE(edate-sdate);
Open c;
Sdate:=dbms_utility.get_time;
Fetch c bulk collect into vnes;
Edate:=dbms_utility.get_time;
Close c;
DBMS_OUTPUT.PUT_LINE(edate-sdate);
End;
-- not existed
Raju Ch
End loop;
End p;
Begin
p(vnes);
end;
using collections for return datatype:DECLARE
TYPE nes IS TABLE OF VARCHAR2 (10);
vnes
:=nes(a,b,c,d);
Y nes:=nes();
Function fun(x nes) return nes is
Begin
Return x;
End fun;
Begin
Y:=fun(vnes);
For I in Y.first..Y.last loop
DBMS_OUTPUT.PUT_LINE(Y(i));
End loop;
End;
nes ();
:= 0;
:= 0;
:= 0;
INTO vnes
Raju Ch
Using save exception (10g): It filters outs the error records and allows the other records to process, instead of cancelling all the records.
Save exception saves the errors and we can retrieve the error by using %bulk exception.
Declare
Type nes is table of varchar2(10);
Vnes nes:=(x,a,y,b,z);
Begin
For all I in vnes.first..vnes.last
Save exception
Insert into contab values(values (i));
Exception
When others then
For I in sql%bulk_exceptions.count loop
DBMS_OUTPUT.PUT_LINE(sql%bulk_exceptions(i).error_index|| ||sql%bulk_exceptions(i).error_code);
End loop;
End;
Error-code displays the error code without -sign
Indeces(index/subscript) of values of:Eg for values of clause: Here we are comparing one collection values with another collection of indices values.
Declare
Type nes is table of varchar2(10);
Vnes nes:=nes(a,b,c,d,e,f);
Type nes1 is table of pls_integer;
Vnes1 nes1:=nes1(1,3,5);
Begin
For all I in vnes values of vnes1
Insert into contab values of vnes(i);
End;
Output:
Loc
Raju Ch
A
C
C
Table function:It is a function which acts as same to that of table to SQL engine with the help of table operator called table.
We provide table function in from clause of a select statement.
SQL engine cant identify it as a function.
Note:Table functions have to always return data from collections only.
But we cant provide functions in from clause.
Eg:Create or replace function colfun return nes is
Vnes nes:=nes(a,b,c,d,e,f)
Begin
Return vnes;
-- here vnes always collection.
End;
Select * from table(col_fun);
Column_val -- it internally pseudo column generates, introduced from 10g
A
B
C
D
E
F
Table function data will be displayed under a column name called column_val which is a pseudo column.
Dynamic SQl and Dynamic PL/SQL:Dynamic SQL statements are the statements which are constructed (or) get framed (or) build up at the time of
execution.
When an SQL statement get framed before of compilation time those are called static SQL.
Creation of PL/SQL program at runtime is called as dynamic PL/SQL.
To execute dynamic SQL and PL/SQL we use
Raju Ch
1. Execute immediate(statement).
2. DBMS_SQL(packages)
Note:-Dynamic SQL statement falls pray, to SQL injections. We can also execute immediate to execute DDL
statements in the program which is normally not possible.
Syntax for execute immediate:Execute immediate string [into {var1,var2..}]
[using[in/out/inout]] bind_variable,..];
Raju Ch
Raju Ch
Exec p(king);
King 10
Exec p(null union select ename,sal from emp); (here getting unintended data is not possible).
Note:When we know all the SQl identifiers (column, table names) before of fraiming a statement, in that case only
it is possible to convert the dynamic SQL statements into static SQl which means it is not possible to convert
all the dynamic SQL statements static if this is the case then mien/mise the attacking of SQL injection by
using bind argument as shown in the following snippet (or) eg.
In addition with protectiong the PL/SQL code from SQL injection it also possible to enhance the performance
immeyely(more effectively).
Using bind arguments in dynamic SQL will avoid hard parsing(buffer myss) and promote soft parsing(buffer
hit).
For the above eg just change
Begin
Open vrec for select enaame, deptno from emp where ename=: using x_name;
Loop
-- remaining structure is same.
Exec p(king);
Exec p(null union select ename,sal from emp);
Finally we will reduce the SQL injection by sanitizing the user inputs with the help of an APL i.e
DBMS_assert(package).
While tunning the PL/SQL code avoid implicit conversion which ia a burden to the ename as server as such
in the following.
Eg:DECLARE
Stime
NUMBER := 0;
Etime
NUMBER := 0;
V
VARCHAR2 (10);
BEGIN
Stime := DBMS_UTILITY.get_time;
FOR I IN 1 .. 1000
LOOP
V := I;
END LOOP;
Etime := DBMS_UTILITY.get_time;
DBMS_OUTPUT.PUT_LINE (edate_sdate);
END;
DECLARE
Stime
NUMBER := 0;
Etime
NUMBER := 0;
V
NUMBER (5);
BEGIN
Stime := DBMS_UTILITY.get_time;
Raju Ch
FOR I IN 1 .. 1000
LOOP
V := i;
END LOOP;
Ctime := DBMS_UTILITY.get_time;
DBMS_OUTPUT.PUT_LINE (edate - sdate);
END;
cursor eg:DECLARE
CURSOR c
IS
SELECT * FROM emp;
-here just defines the definition c.
vrow
c%ROWTYPE;
BEGIN
OPEN c;
--here select stmt get executes and opens the memory area and gets data.
LOOP
FETCH c INTO vrow;
--here fetching will happen.
Raju Ch
DBMS_OUTPUT.PUT_LINE (vrow.ename);
IF c%NOTFOUND
THEN
EXIT;
END IF;
END LOOP;
--(1)
CLOSE C;
END;
IN case of (1) we can write
IF C%ROWCOUNT=3 THEN
EXIT;
END IF;
If you write like this we can stop the program after 3rd record. In this case for loop is not prefereable, simple
loop is prefereable.
Paramatarised cursor eg:Declare
Cursor c(x number) is select * from emp where deptno:=x;
Vrow emp%rowtype;
Vno number(5):=&n;
Vnol number(5):=&m;
Begin
Open c(vno);
Loop
Fetch c into vrow;
DBMS_OUTPUT.PUT_LINE(vrow.ename)
Exit when c%not found;
End loop;
Close c;
Open c(vnol);
Loop
Fetch c into vrow;
DBMS_OUTPUT.PUT_LINE(vrow.ename);
Exit when c%not found;
End loop;
Close c;
Before open c:
% is open -F
% found
E
% notfound -E
% rowcount -E
After open c:
% is open -T
% found
-T
% notfound -F
% rowcount -0
After fetch: (1st fetch)
% is open
-T
% found
-1
Raju Ch
% notfound -F
% rowcount -1
After close c:
% is open -F
% found
-E
% notfound -E
% rowcount -E
We can use cursor variable as a parameter in stored procedures
Create or replace function f return sys_refcursor is vrec sys_refcursor;
Begin
Open vrec for select * from emp;
Return vrec;--return statement
End f;
We can also use sys_refcursor datatype for function return value (or) using cursor variable as a return value
in function.
Calling:Var refvar refcursor;
Exec :refvar:=f;
Print refvar;--emp data:14records.
Create or replace function f(vrec out sys_refcursor) return Boolean
Begin
Open vrec for select * from emp;
Close vrec;
Return true;
End;
Declare
Vrec1 sys_refcursor;
V Boolean;
Vrow emp%rowtype;
Begin
V:=f(vrec1);
Loop
Fetch vrec1 into vrow;
DBMS_OUTPUT.PUT_LINE(vrow.ename);
Exit when vrec1%not found;
End loop;
End;
CREATE OR REPLACE FUNCTION f (vrec OUT SYS_REFCURSOR)
RETURN BOOLEAN
IS
Vrow
emp%ROWTYPE;
BEGIN
OPEN vrec FOR SELECT * FROM emp;
FETCH vrec INTO vrow;
RETURN TRUE;
END f;
Raju Ch
DECLARE
Vrec1
SYS_REFCURSOR;
V
BOOLEAN;
Vrow
emp%ROWTYPE;
BEGIN
V := f (vrec1);
LOOP
FETCH vrec1 INTO vrow;
DBMS_OUTPUT.PUT_LINE (vrow.ename);
EXIT WHEN vrec1%not found;
End loop;
End;
Analyzing PL/SQL code:By using format-call-stack procedure we will sequentially trace out the program calls so , to analyse the
coading as shown in the following eg. (or) snippet.
Raju Ch
Object
Procedure APPs-p
Procedure
Procedure apps.p2
Anonymous block
*/
Note:If you want to execute to multiple lines we give like this.
/*
..
/*
..
*/
.
.....
*/
Note:-
Raju Ch
Instead of trigger:This trigger is for views, to perform DML operations on complex views will not be allowed directly, but by
using instead of trigger it is passible.
This trigger is always a rowlevel trigger even if you wont mention the for each row clause.
Defining instead of trigger on tables ends with an error.
Create table vtabl(sno number(5));
Create table vtab2(loc varchar2(10);
Create view comview as select * from vtab1, vtab2;
Insert into comview values(10,hyd);
Error:
Can not modify a column which maps to a non key preserved data.
Create or replace triggr comtrig
Instead of insert on comview;
Begin
Insert into vtab1 values(:new.sno);
Insert into vtab2 values(:new.loc);
End;
Insert into comview values(10,hyd);--here insertion is successfully happening on view.
Note:-DML operation cant perform on complex views. But as in the above case trigger is inserting the values
before insertion.
Mutating error:We get this error when a row level trigger attempts to read or write the table from which it was raised.
You wont get this error in statement level.
Create or replace trigger muttrig Before update on vtab1
For each row
Declare
Vno number95);
Begin
Select sno into vno from vtab1 where sno=30;
End;
Update vtab1 set sno=50;
Error: table apps.vtab1 is mutating, trigger/function may not see it.
To Avoid Mutating Errors We Use Pragma Atonomous Transaction (or) we can also use statement level
trigger.