You are on page 1of 34

1

PROCEDURES AND FUNCTIONS


Subprograms in PL/SQL
2

 PL/SQL blocks are anonymous, can not be


called from other PL/SQL blocks
 Subprogram is a named PL/SQL block that
could be either
Procedure, or
Function
Syntax for Creating a Procedure
3

 Stored Procedure
A stored procedure is a named PL/SQL block that
performs an action. It can be stored in the database
as a database object for repeated execution.

CREATE [ OR REPLACE ] PROCEDURE proc_name[(argument


[mode] data type, argument [mode] data type,……)]
-- PROCEDURES and FUNCTIONS may or may not accept arguments
IS
Local PL/SQL variable declarations
BEGIN
Define action performed by the procedure
EXCEPTION
Handle exceptions, if any
END [ proc_name];
RAISE_APPLICATION_ERROR
4
Procedure
 This procedure is used to display error
messages along with error numbers
 Example

RAISE_APPLICATION_ERROR(-20001, ‘Invalid
Employee’);
 Note:
When called, RAISE_APPLICATION_ERROR ends a subprogram, rolls
back any database changes it made, and returns a user-defined error
message to the application
Error numbers should be between -20000 and -20999
Parameters Modes in Procedures and Functions

Formal parameters can have three modes IN, OUT or IN OUT which decides
the behavior of parameters

IN OUT IN OUT

Default parameter mode Must be specified Must be specified

Value is passed into Value is returned to the Value is passed into


subprograms calling environment subprogram and formatted
value is returned to the calling
environment

Formal parameter acts as a Formal parameter acts Formal parameter acts as a


constant inside a as a uninitialized initialized variable
subprogram variable
Actual parameter can be an Actual parameter must Actual parameter must be
expression, constant or be a variable a variable
initialized variable
IN Parameter: Example
6

CREATE OR REPLACE PROCEDURE


raise_salary (p_eno emp.empno%TYPE)
IS
vsal emp.sal%type;
BEGIN

SELECT sal into vsal FROM emp WHERE empno=p_eno;


IF vsal <2000 THEN
UPDATE emp SET sal = sal+vsal * 0.1 WHERE empno = p_eno;
END IF;
-- An exception handler to raise error if empno is not valid
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE (‘Empno does not exist’);
END raise_salary;
Invoking a Procedure
7

 There are two methods to Invoke a Procedure


Invoke a Procedure from another PL/SQL block
e.g.
BEGIN
raise_salary(1002);
END;

Invoke a procedure from SQL*Plus environment by using


EXECUTE command
e.g.
-- PROCEDURE call with parameter
EXECUTE raise_salary(1002);

Note: If no parameters are specified for a procedure, directly specify procedure name
without any parenthesis
e. g. EXECUTE procedure_name;
OUT Parameter: Example
8

CREATE OR REPLACE PROCEDURE query_emp


( p_eno IN emp.empno%TYPE,
p_name OUT emp.ename%TYPE,
p_sal OUT emp.sal%TYPE)
IS
BEGIN
SELECT ename , sal INTO p_name , p_sal FROM emp
WHERE empno = p_eno;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20001,’ Employee does not exist’);
END query_emp;
Invoking a Procedure Having OUT Parameters
9

SQL> VARIABLE name VARCHAR2(20)


SQL> VARIABLE salary NUMBER

SQL> EXECUTE query_emp(1001,:name,:salary)


SQL> PRINT name salary

 Note: The use of colon (:) is to reference the


host variable in the EXECUTE syntax
IN OUT Parameter: Example
10

CREATE OR REPLACE PROCEDURE emp_salary_increase


(p_emp_id IN emp.empno%TYPE, p_salary IN OUT emp.sal%TYPE)
IS
BEGIN
IF p_salary between 1000 and 2000 THEN
p_salary := p_salary * 1.2;
ELSIF p_salary between 2000 and 3000 THEN
p_salary := p_salary * 1.3;
ELSIF p_salary > 3000 THEN
p_salary := p_salary* 1.4;
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/
IN OUT Parameter (Contd.)
11

 This PL/SQL block shows how to execute the above


'emp_salary_increase' procedure
DECLARE
CURSOR updated_sal IS SELECT empno, sal FROM emp;
pre_sal emp.sal%TYPE;
BEGIN
FOR emp_rec IN updated_sal LOOP
pre_sal := emp_rec.sal;
emp_salary_increase (emp_rec.empno, emp_rec.sal);
DBMS_OUTPUT.PUT_LINE(' The salary of ' ||
emp_rec.empno ||' will be increased from '|| emp_rec.sal || ' to '|| (emp_rec.sal +
pre_sal));
END LOOP;
END;
/
Syntax for Creating a Function
12

 A function is a named PL/SQL block that


performs a task and returns a value to the calling
environment.
 Syntax:
CREATE [ OR REPLACE ] FUNCTION function_name
[( argument [mode] data type, argument [mode] data type )]
RETURN data type
IS
Local PL/SQL variable declarations
BEGIN
Define task performed by the function and return
result using RETURN statement
EXCEPTION
Handle exceptions if any
END [ function_name];
Functions in PL/SQL
13

 Example 1

CREATE OR REPLACE FUNCTION cal_bonus


( p_eno emp.empno%TYPE )
RETURN NUMBER
IS
v_sal emp.sal%TYPE;
BEGIN
SELECT sal INTO v_sal FROM emp
WHERE empno = p_eno;
RETURN (v_sal * 0.1);
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN -1;
END;
How to call function?
14

 declare
 p_sal emp.sal%TYPE;
 p_empno emp.empno%TYPE := &empno;
 begin
 p_sal := cal_bonus(p_empno);
 update emp set sal = sal + p_sal where empno = p_empno;
 commit;
 --dbms_output.put_line(p_sal);
 end;
 /
Functions in PL/SQL
15

 Example 2

CREATE OR REPLACE FUNCTION chk_dept


(p_deptno dept.deptno%TYPE) RETURN BOOLEAN
IS
v_deptno dept.deptno%type;
BEGIN
SELECT deptno into v_deptno FROM dept
WHERE deptno = p_deptno;
RETURN TRUE;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN FALSE;
END;
Difference between Procedures and Functions

Procedures Functions

Execute as a PL/SQL statement Invoked as part of an expression

Do not contain RETURN clause in the Must contain a RETURN clause in the
header header

Can return none, one or many values with Must return a value using the RETURN
the help of OUT & IN OUT parameters clause. Can also return one or many values
with the help of OUT and IN OUT
parameters.

1
6
Dropping PROCEDURES and FUNCTIONS
17

 To Delete a PROCEDURE:

DROP PROCEDURE <Procedurename>;


e.g.
DROP PROCEDURE emp_salary_increase;

 To Delete a FUNCTION:

DROP FUNCTION < Functionname >;


e.g.
DROP FUNCTION chk_dept;
Local Procedures and Functions within a Stored
Subprogram
18

CREATE OR REPLACE PROCEDURE emp_pro AS


CURSOR c_allEmp IS SELECT deptno, ename FROM emp;
v_dname dept.dname%TYPE;
-- Local function ,local to the procedure which will return the dept name for an employee
FUNCTION show_deptname (p_dno dept.deptno%TYPE) RETURN VARCHAR2 IS
v_dname dept.dname%TYPE;
BEGIN
SELECT dname INTO v_dname FROM dept WHERE deptno = p_dno;
RETURN v_dname;
END show_deptname;
BEGIN
FOR v_rec IN c_allEmp LOOP
v_dname := show_deptname (v_rec.deptno);
DBMS_OUTPUT.PUT_LINE(v_rec.ename ||' belongs to '||v_dname);
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Wrong department number');
END emp_pro;
Data Dictionary View
19

 USER_SOURCE
Is used to obtain the text of a stored procedure or a stored
function
 USER_ERRORS
Is used to find out the compilation errors in the subprogram,
currently getting compiled
One can use the SQL*Plus command SHOW ERRORS,
instead of firing a SELECT query on USER_ERRORS

 USER_OBJECTS
Is used to get the details of all the objects created in a
particular schema
 USER_PROCEDURES
Is used to get the details of all procedures in that user’s
schema
20

DML TRIGGERS
Database Triggers
 Triggers are named PL/SQL blocks with
declarative, executable, and exception handling
sections
 A trigger is executed implicitly whenever the
triggering event takes place
 Triggers do not accept arguments
 Like packages, triggers are stored database
objects and can not be local to a block

21
Stored Procedures vs Database
Triggers

Stored Procedures Triggers

A procedure is called explicitly by A trigger executes implicitly in


a user, application or a trigger response to an event, such as an
update operation on a table

Can not be inactive We can enable and disable according to


the need

Can have parameters Can not have parameters

No restriction on the size of a procedure There may be a restriction on the size of


a trigger depending on the version of
oracle used

2
2
DML Triggers
 Application:
To impose complex integrity constraints not
possible through declarative constraints
To audit information in a table
To create replica of a table etc.
Security reasons

23
DML Triggers
 DML Trigger Components
Part Description Possible Values

Trigger Timing When the trigger fires in BEFORE


relation to the triggering event AFTER

Triggering Event Which data manipulation INSERT


operation on the table or view, UPDATE
causes the trigger to fire DELETE

Trigger Type How many times the trigger Statement


body executes Row

Trigger Body What action the trigger Complete PL/SQL Block


performs
24
Statement Triggers
 The trigger body executes only once for the
triggering event. This is the default.

 Syntax:

CREATE [ OR REPLACE ] TRIGGER trigger_name


trigger_timing event1 [ OR event2 OR event3 ]
ON table_name
PL/SQL Block;

25
Statement Triggers: Example

CREATE OR REPLACE TRIGGER chk_time


BEFORE INSERT OR UPDATE OR DELETE
ON emp
BEGIN
IF (TO_CHAR(sysdate,’DY’) IN (‘SAT’,’SUN’)) OR (TO_CHAR(sysdate,
’HH24’) NOT
BETWEEN ‘08’ AND ‘18’)
THEN
RAISE_APPLICATION_ERROR(-20400, ‘You can
not perform any DML Operation’);
END IF;
END;

26
Row Triggers
 The trigger body executes once for each row
affected by the triggering event.
 Syntax for creating Row Triggers:
  CREATE [ OR REPLACE ] TRIGGER trigger_name
trigger_timing event1 [ OR event2 OR event3 ]
ON table_name
FOR EACH ROW
[WHEN condition]
PL/SQL Block;
  FOR EACH ROW: Designates the trigger to be a row trigger
WHEN condition: Specifies the trigger restriction
For the UPDATE event there is an optional clause
[OF column_name[,column_name…..]] 27
Using OLD and NEW Qualifiers
 In a ROW LEVEL trigger all the column values of the current row, before
modification and after modification, are available to the trigger block as
local variables. To access these values, the OLD and NEW quantifiers are
used

e.g. :OLD.empno, :NEW.deptno


Data Operation Old Value New Value

INSERT NULL Inserted Value

UPDATE Value before update Value after update

DELETE Value before delete NULL

28
:old and :new variables:
Example
CREATE TABLE emp_hist
( empno NUMBER(5),
oldSal NUMBER(10),
newSal NUMBER(10));

CREATE OR REPLACE TRIGGER LOG_TRIG


AFTER UPDATE OF sal ON emp
FOR EACH ROW
BEGIN
IF :NEW.sal < :OLD.sal THEN
RAISE_APPLICATION_ERROR(-20101,’Salary cannot be decremented’);
ELSE
INSERT INTO emp_hist VALUES
(:OLD.empno, :OLD.sal, :NEW.sal);
END IF;
END; 29
WHEN Clause
 Valid for row triggers only
 Trigger body executes for those rows that
meet the condition
 Evaluates for each row
 OLD and NEW variables can be referenced here
 For OLD and NEW variables we should not use
colon (:) in the WHEN condition

30
WHEN Clause

CREATE OR REPLACE TRIGGER TRIG_WHEN


AFTER UPDATE OF sal ON emp
FOR EACH ROW
WHEN (old.sal > new.sal)
BEGIN
RAISE_APPLICATION_ERROR(-20009, ‘Cannot
reduce salary’);
END;
31
Use of TCL Commands in a
Trigger
CREATE OR REPLACE TRIGGER tab1_trig
AFTER insert ON tab1
DECLARE
-- declare the trigger as separate transaction from the
-- triggering event
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO emp_log VALUES (SYSDATE, 'Insert on emp');
COMMIT; -- allowed only in autonomous triggers
END;

SQL> INSERT INTO emp(empno) VALUES (1);


1 row created.

32
Managing Triggers
 Disable / Enable trigger:
ALTER TRIGGER trigger_name ENABLE/DISABLE;

 Disable / Enable all triggers for a table:


ALTER TABLE table_name DISABLE/ENABLE ALL TRIGGERS;

 Dropping Triggers:
DROP TRIGGER trigger_name;

 USER_TRIGGERS data dictionary view:


To query database trigger details stored in a database dictionary

33
34

THANK YOU

You might also like