0% found this document useful (0 votes)
27 views17 pages

Unit V

Download as docx, pdf, or txt
Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1/ 17

Unit V

PL/SQL Named blocks

PL/SQL - Procedures
A subprogram is a program unit/module that performs a particular task. These
subprograms are combined to form larger programs. This is basically called the
'Modular design'. A subprogram can be invoked by another subprogram or program
which is called the calling program.
A subprogram can be created −

 At the schema level


 Inside a package
 Inside a PL/SQL block
At the schema level, subprogram is a standalone subprogram. It is created with the
CREATE PROCEDURE or the CREATE FUNCTION statement. It is stored in the
database and can be deleted with the DROP PROCEDURE or DROP FUNCTION
statement.
A subprogram created inside a package is a packaged subprogram. It is stored in the
database and can be deleted only when the package is deleted with the DROP
PACKAGE statement. We will discuss packages in the chapter 'PL/SQL - Packages'.
PL/SQL subprograms are named PL/SQL blocks that can be invoked with a set of
parameters. PL/SQL provides two kinds of subprograms −
 Functions − These subprograms return a single value; mainly used to compute and return a
value.
 Procedures − These subprograms do not return a value directly; mainly used to perform an
action.
This chapter is going to cover important aspects of a PL/SQL procedure. We will
discuss PL/SQL function in the next chapter.

Parts of a PL/SQL Subprogram


Each PL/SQL subprogram has a name, and may also have a parameter list. Like
anonymous PL/SQL blocks, the named blocks will also have the following three parts −

S.N Parts & Description


o

1
Declarative Part
It is an optional part. However, the declarative part for a subprogram does not start with
the DECLARE keyword. It contains declarations of types, cursors, constants, variables,
exceptions, and nested subprograms. These items are local to the subprogram and cease
to exist when the subprogram completes execution.

Executable Part
2
This is a mandatory part and contains statements that perform the designated action.

Exception-handling
3
This is again an optional part. It contains the code that handles run-time errors.

Creating a Procedure
A procedure is created with the CREATE OR REPLACE PROCEDURE statement.
The simplified syntax for the CREATE OR REPLACE PROCEDURE statement is as
follows −

CREATE [OR REPLACE] PROCEDURE procedure_name


[(parameter_name [IN | OUT | IN OUT] type [, ...])]
{IS | AS}
BEGIN
< procedure_body >
END procedure_name;

Where,
 procedure-name specifies the name of the procedure.
 [OR REPLACE] option allows the modification of an existing procedure.
 The optional parameter list contains name, mode and types of the
parameters. IN represents the value that will be passed from outside and OUT represents
the parameter that will be used to return a value outside of the procedure.
 procedure-body contains the executable part.
 The AS keyword is used instead of the IS keyword for creating a standalone procedure.

Example
The following example creates a simple procedure that displays the string 'Hello
World!' on the screen when executed.

CREATE OR REPLACE PROCEDURE greetings


AS
BEGIN
dbms_output.put_line('Hello World!');
END;
/

When the above code is executed using the SQL prompt, it will produce the following
result −
Procedure created.

Executing a Standalone Procedure


A standalone procedure can be called in two ways −
 Using the EXECUTE keyword
 Calling the name of the procedure from a PL/SQL block
The above procedure named 'greetings' can be called with the EXECUTE keyword as

EXECUTE greetings;
The above call will display −
Hello World

PL/SQL procedure successfully completed.


The procedure can also be called from another PL/SQL block −

BEGIN
greetings;
END;
/

The above call will display −


Hello World

PL/SQL procedure successfully completed.

Deleting a Standalone Procedure


A standalone procedure is deleted with the DROP PROCEDURE statement. Syntax for
deleting a procedure is −
DROP PROCEDURE procedure-name;
You can drop the greetings procedure by using the following statement −
DROP PROCEDURE greetings;

Parameter Modes in PL/SQL Subprograms


The following table lists out the parameter modes in PL/SQL subprograms −
S.N Parameter Mode & Description
o

IN
An IN parameter lets you pass a value to the subprogram. It is a read-only parameter.
1 Inside the subprogram, an IN parameter acts like a constant. It cannot be assigned a
value. You can pass a constant, literal, initialized variable, or expression as an IN
parameter. You can also initialize it to a default value; however, in that case, it is omitted
from the subprogram call. It is the default mode of parameter passing. Parameters are
passed by reference.

OUT

2 An OUT parameter returns a value to the calling program. Inside the subprogram, an OUT
parameter acts like a variable. You can change its value and reference the value after
assigning it. The actual parameter must be variable and it is passed by value.

IN OUT
An IN OUT parameter passes an initial value to a subprogram and returns an updated
value to the caller. It can be assigned a value and the value can be read.
3
The actual parameter corresponding to an IN OUT formal parameter must be a variable,
not a constant or an expression. Formal parameter must be assigned a value. Actual
parameter is passed by value.

IN & OUT Mode Example 1


This program finds the minimum of two values. Here, the procedure takes two numbers
using the IN mode and returns their minimum using the OUT parameters.

DECLARE
a number;
b number;
c number;
PROCEDURE findMin(x IN number, y IN number, z OUT number) IS
BEGIN
IF x < y THEN
z:= x;
ELSE
z:= y;
END IF;
END;
BEGIN
a:= 23;
b:= 45;
findMin(a, b, c);
dbms_output.put_line(' Minimum of (23, 45) : ' || c);
END;
/

When the above code is executed at the SQL prompt, it produces the following result −
Minimum of (23, 45) : 23

PL/SQL procedure successfully completed.

IN & OUT Mode Example 2


This procedure computes the square of value of a passed value. This example shows
how we can use the same parameter to accept a value and then return another result.

DECLARE
a number;
PROCEDURE squareNum(x IN OUT number) IS
BEGIN
x := x * x;
END;
BEGIN
a:= 23;
squareNum(a);
dbms_output.put_line(' Square of (23): ' || a);
END;
/

When the above code is executed at the SQL prompt, it produces the following result −
Square of (23): 529

PL/SQL procedure successfully completed.

Methods for Passing Parameters


Actual parameters can be passed in three ways −

 Positional notation
 Named notation
 Mixed notation

Positional Notation
In positional notation, you can call the procedure as −
findMin(a, b, c, d);
In positional notation, the first actual parameter is substituted for the first formal
parameter; the second actual parameter is substituted for the second formal
parameter, and so on. So, a is substituted for x, b is substituted for y, c is substituted
for z and d is substituted for m.

Named Notation
In named notation, the actual parameter is associated with the formal parameter using
the arrow symbol ( => ). The procedure call will be like the following −
findMin(x => a, y => b, z => c, m => d);

Mixed Notation
In mixed notation, you can mix both notations in procedure call; however, the positional
notation should precede the named notation.
The following call is legal −
findMin(a, b, c, m => d);
However, this is not legal:
findMin(x => a, b, c, d);

PL/SQL - Functions
A function is same as a procedure except that it returns a value. Therefore, all the
discussions of the previous chapter are true for functions too.

Creating a Function
A standalone function is created using the CREATE FUNCTION statement. The
simplified syntax for the CREATE OR REPLACE PROCEDURE statement is as
follows −
CREATE [OR REPLACE] FUNCTION function_name
[(parameter_name [IN | OUT | IN OUT] type [, ...])]
RETURN return_datatype
{IS | AS}
BEGIN
< function_body >
END [function_name];
Where,
 function-name specifies the name of the function.
 [OR REPLACE] option allows the modification of an existing function.
 The optional parameter list contains name, mode and types of the parameters. IN
represents the value that will be passed from outside and OUT represents the parameter
that will be used to return a value outside of the procedure.
 The function must contain a return statement.
 The RETURN clause specifies the data type you are going to return from the function.
 function-body contains the executable part.
 The AS keyword is used instead of the IS keyword for creating a standalone function.

Example
The following example illustrates how to create and call a standalone function. This
function returns the total number of CUSTOMERS in the customers table.
We will use the CUSTOMERS table, which we had created in the PL/SQL
Variables chapter −
Select * from customers;

+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
+----+----------+-----+-----------+----------+
CREATE OR REPLACE FUNCTION totalCustomers
RETURN number IS
total number(2) := 0;
BEGIN
SELECT count(*) into total
FROM customers;

RETURN total;
END;
/

When the above code is executed using the SQL prompt, it will produce the following
result −
Function created.

Calling a Function
While creating a function, you give a definition of what the function has to do. To use a
function, you will have to call that function to perform the defined task. When a program
calls a function, the program control is transferred to the called function.
A called function performs the defined task and when its return statement is executed
or when the last end statement is reached, it returns the program control back to the
main program.
To call a function, you simply need to pass the required parameters along with the
function name and if the function returns a value, then you can store the returned
value. Following program calls the function totalCustomers from an anonymous block

DECLARE
c number(2);
BEGIN
c := totalCustomers();
dbms_output.put_line('Total no. of Customers: ' || c);
END;
/

When the above code is executed at the SQL prompt, it produces the following result −
Total no. of Customers: 6

PL/SQL procedure successfully completed.

Example
The following example demonstrates Declaring, Defining, and Invoking a Simple
PL/SQL Function that computes and returns the maximum of two values.

DECLARE
a number;
b number;
c number;
FUNCTION findMax(x IN number, y IN number)
RETURN number
IS
z number;
BEGIN
IF x > y THEN
z:= x;
ELSE
Z:= y;
END IF;
RETURN z;
END;
BEGIN
a:= 23;
b:= 45;
c := findMax(a, b);
dbms_output.put_line(' Maximum of (23,45): ' || c);
END;
/

When the above code is executed at the SQL prompt, it produces the following result −
Maximum of (23,45): 45

PL/SQL procedure successfully completed.

PL/SQL Recursive Functions


We have seen that a program or subprogram may call another subprogram. When a
subprogram calls itself, it is referred to as a recursive call and the process is known
as recursion.
To illustrate the concept, let us calculate the factorial of a number. Factorial of a
number n is defined as −
n! = n*(n-1)!
= n*(n-1)*(n-2)!
...
= n*(n-1)*(n-2)*(n-3)... 1
The following program calculates the factorial of a given number by calling itself
recursively −

DECLARE
num number;
factorial number;

FUNCTION fact(x number)


RETURN number
IS
f number;
BEGIN
IF x=0 THEN
f := 1;
ELSE
f := x * fact(x-1);
END IF;
RETURN f;
END;

BEGIN
num:= 6;
factorial := fact(num);
dbms_output.put_line(' Factorial '|| num || ' is ' ||
factorial);
END;
/

When the above code is executed at the SQL prompt, it produces the following result −
Factorial 6 is 720

PL/SQL procedure successfully completed.


Package
Packages are schema objects that groups logically related PL/SQL types, variables,
and subprograms.
A package will have two mandatory parts −

 Package specification
 Package body or definition

Package Specification
The specification is the interface to the package. It just DECLARES the types,
variables, constants, exceptions, cursors, and subprograms that can be referenced
from outside the package. In other words, it contains all information about the content
of the package, but excludes the code for the subprograms.
All objects placed in the specification are called public objects. Any subprogram not in
the package specification but coded in the package body is called a private object.
The following code snippet shows a package specification having a single procedure.
You can have many global variables defined and multiple procedures or functions
inside a package.

CREATE PACKAGE cust_sal AS


PROCEDURE find_sal(c_id customers.id%type);
END cust_sal;
/

When the above code is executed at the SQL prompt, it produces the following result −
Package created.

Package Body
The package body has the codes for various methods declared in the package
specification and other private declarations, which are hidden from the code outside
the package.
The CREATE PACKAGE BODY Statement is used for creating the package body. The
following code snippet shows the package body declaration for the cust_sal package
created above. I assumed that we already have CUSTOMERS table created in our
database as mentioned in the PL/SQL - Variables chapter.

CREATE OR REPLACE PACKAGE BODY cust_sal AS

PROCEDURE find_sal(c_id customers.id%TYPE) IS


c_sal customers.salary%TYPE;
BEGIN
SELECT salary INTO c_sal
FROM customers
WHERE id = c_id;
dbms_output.put_line('Salary: '|| c_sal);
END find_sal;
END cust_sal;
/

When the above code is executed at the SQL prompt, it produces the following result −
Package body created.

Using the Package Elements


The package elements (variables, procedures or functions) are accessed with the
following syntax −
package_name.element_name;
Consider, we already have created the above package in our database schema, the
following program uses the find_sal method of the cust_sal package −

DECLARE
code customers.id%type := &cc_id;
BEGIN
cust_sal.find_sal(code);
END;
/

When the above code is executed at the SQL prompt, it prompts to enter the customer
ID and when you enter an ID, it displays the corresponding salary as follows −
Enter value for cc_id: 1
Salary: 3000

PL/SQL procedure successfully completed.

Example
The following program provides a more complete package. We will use the
CUSTOMERS table stored in our database with the following records −
Select * from customers;

+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 3000.00 |
| 2 | Khilan | 25 | Delhi | 3000.00 |
| 3 | kaushik | 23 | Kota | 3000.00 |
| 4 | Chaitali | 25 | Mumbai | 7500.00 |
| 5 | Hardik | 27 | Bhopal | 9500.00 |
| 6 | Komal | 22 | MP | 5500.00 |
+----+----------+-----+-----------+----------+

The Package Specification


CREATE OR REPLACE PACKAGE c_package AS
-- Adds a customer
PROCEDURE addCustomer(c_id customers.id%type,
c_name customerS.No.ame%type,
c_age customers.age%type,
c_addr customers.address%type,
c_sal customers.salary%type);

-- Removes a customer
PROCEDURE delCustomer(c_id customers.id%TYPE);
--Lists all customers
PROCEDURE listCustomer;

END c_package;
/

When the above code is executed at the SQL prompt, it creates the above package
and displays the following result −
Package created.

Creating the Package Body


CREATE OR REPLACE PACKAGE BODY c_package AS
PROCEDURE addCustomer(c_id customers.id%type,
c_name customerS.No.ame%type,
c_age customers.age%type,
c_addr customers.address%type,
c_sal customers.salary%type)
IS
BEGIN
INSERT INTO customers (id,name,age,address,salary)
VALUES(c_id, c_name, c_age, c_addr, c_sal);
END addCustomer;

PROCEDURE delCustomer(c_id customers.id%type) IS


BEGIN
DELETE FROM customers
WHERE id = c_id;
END delCustomer;

PROCEDURE listCustomer IS
CURSOR c_customers is
SELECT name FROM customers;
TYPE c_list is TABLE OF customers.Name%type;
name_list c_list := c_list();
counter integer :=0;
BEGIN
FOR n IN c_customers LOOP
counter := counter +1;
name_list.extend;
name_list(counter) := n.name;
dbms_output.put_line('Customer(' ||counter|| ')'||
name_list(counter));
END LOOP;
END listCustomer;

END c_package;
/

The above example makes use of the nested table. We will discuss the concept of
nested table in the next chapter.
When the above code is executed at the SQL prompt, it produces the following result −
Package body created.

Using The Package


The following program uses the methods declared and defined in the
package c_package.

DECLARE
code customers.id%type:= 8;
BEGIN
c_package.addcustomer(7, 'Rajnish', 25, 'Chennai', 3500);
c_package.addcustomer(8, 'Subham', 32, 'Delhi', 7500);
c_package.listcustomer;
c_package.delcustomer(code);
c_package.listcustomer;
END;
/

When the above code is executed at the SQL prompt, it produces the following result −
Customer(1): Ramesh
Customer(2): Khilan
Customer(3): kaushik
Customer(4): Chaitali
Customer(5): Hardik
Customer(6): Komal
Customer(7): Rajnish
Customer(8): Subham
Customer(1): Ramesh
Customer(2): Khilan
Customer(3): kaushik
Customer(4): Chaitali
Customer(5): Hardik
Customer(6): Komal
Customer(7): Rajnish

PL/SQL procedure successfully completed

PL/SQL - Triggers
Triggers are stored programs, which are automatically executed or fired when some
events occur. Triggers are, in fact, written to be executed in response to any of the
following events −
 A database manipulation (DML) statement (DELETE, INSERT, or UPDATE)
 A database definition (DDL) statement (CREATE, ALTER, or DROP).
 A database operation (SERVERERROR, LOGON, LOGOFF, STARTUP, or SHUTDOWN).
Triggers can be defined on the table, view, schema, or database with which the event
is associated.

Benefits of Triggers
Triggers can be written for the following purposes −

 Generating some derived column values automatically


 Enforcing referential integrity
 Event logging and storing information on table access
 Auditing
 Synchronous replication of tables
 Imposing security authorizations
 Preventing invalid transactions

Creating Triggers
The syntax for creating a trigger is −

CREATE [OR REPLACE ] TRIGGER trigger_name


{BEFORE | AFTER | INSTEAD OF }
{INSERT [OR] | UPDATE [OR] | DELETE}
[OF col_name]
ON table_name
[REFERENCING OLD AS o NEW AS n]
[FOR EACH ROW]
WHEN (condition)
DECLARE
Declaration-statements
BEGIN
Executable-statements
EXCEPTION
Exception-handling-statements
END;

Where,
 CREATE [OR REPLACE] TRIGGER trigger_name − Creates or replaces an existing trigger
with the trigger_name.
 {BEFORE | AFTER | INSTEAD OF} − This specifies when the trigger will be executed. The
INSTEAD OF clause is used for creating trigger on a view.
 {INSERT [OR] | UPDATE [OR] | DELETE} − This specifies the DML operation.
 [OF col_name] − This specifies the column name that will be updated.
 [ON table_name] − This specifies the name of the table associated with the trigger.
 [REFERENCING OLD AS o NEW AS n] − This allows you to refer new and old values for
various DML statements, such as INSERT, UPDATE, and DELETE.
 [FOR EACH ROW] − This specifies a row-level trigger, i.e., the trigger will be executed for
each row being affected. Otherwise the trigger will execute just once when the SQL
statement is executed, which is called a table level trigger.
 WHEN (condition) − This provides a condition for rows for which the trigger would fire. This
clause is valid only for row-level triggers.

Example
To start with, we will be using the CUSTOMERS table we had created and used in the
previous chapters −
Select * from customers;

+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
+----+----------+-----+-----------+----------+
The following program creates a row-level trigger for the customers table that would
fire for INSERT or UPDATE or DELETE operations performed on the CUSTOMERS
table. This trigger will display the salary difference between the old values and new
values −
CREATE OR REPLACE TRIGGER display_salary_changes
BEFORE DELETE OR INSERT OR UPDATE ON customers
FOR EACH ROW
WHEN (NEW.ID > 0)
DECLARE
sal_diff number;
BEGIN
sal_diff := :NEW.salary - :OLD.salary;
dbms_output.put_line('Old salary: ' || :OLD.salary);
dbms_output.put_line('New salary: ' || :NEW.salary);
dbms_output.put_line('Salary difference: ' || sal_diff);
END;
/

When the above code is executed at the SQL prompt, it produces the following result −
Trigger created.
The following points need to be considered here −
 OLD and NEW references are not available for table-level triggers, rather you can use them
for record-level triggers.
 If you want to query the table in the same trigger, then you should use the AFTER keyword,
because triggers can query the table or change it again only after the initial changes are
applied and the table is back in a consistent state.
 The above trigger has been written in such a way that it will fire before any DELETE or
INSERT or UPDATE operation on the table, but you can write your trigger on a single or
multiple operations, for example BEFORE DELETE, which will fire whenever a record will
be deleted using the DELETE operation on the table.

Triggering a Trigger
Let us perform some DML operations on the CUSTOMERS table. Here is one INSERT
statement, which will create a new record in the table −

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)


VALUES (7, 'Kriti', 22, 'HP', 7500.00 );

When a record is created in the CUSTOMERS table, the above create


trigger, display_salary_changes will be fired and it will display the following result −
Old salary:
New salary: 7500
Salary difference:
Because this is a new record, old salary is not available and the above result comes as
null. Let us now perform one more DML operation on the CUSTOMERS table. The
UPDATE statement will update an existing record in the table −

UPDATE customers
SET salary = salary + 500
WHERE id = 2;

When a record is updated in the CUSTOMERS table, the above create


trigger, display_salary_changes will be fired and it will display the following result −
Old salary: 1500
New salary: 2000
Salary difference: 500

You might also like