0% found this document useful (0 votes)
29 views

UNIT 4 PL SQL

Uploaded by

vahaneaniket
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views

UNIT 4 PL SQL

Uploaded by

vahaneaniket
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 45

PL/SQL is a block structured language that enables developers to combine the power

of SQL with procedural statements. All the statements of a block are passed to
oracle engine all at once which increases processing speed and decreases the traffic.
Disadvantages of SQL:
 SQL doesn’t provide the programmers with a technique of condition checking,
looping and branching.
 SQL statements are passed to Oracle engine one at a time which increases traffic
and decreases speed.
 SQL has no facility of error checking during manipulation of data.
Features of PL/SQL:
1. PL/SQL is basically a procedural language, which provides the functionality of
decision making, iteration and many more features of procedural programming
languages.
2. PL/SQL can execute a number of queries in one block using single command.
3. One can create a PL/SQL unit such as procedures, functions, packages, triggers,
and types, which are stored in the database for reuse by applications.
4. PL/SQL provides a feature to handle the exception which occurs in PL/SQL
block known as exception handling block.
5. Applications written in PL/SQL are portable to computer hardware or operating
system where Oracle is operational.
6. PL/SQL Offers extensive error checking.
Differences between SQL and PL/SQL:
SQL PL/SQL

PL/SQL is a block of codes that used to write


SQL is a single query that is used to the entire program blocks/ procedure/
perform DML and DDL operations. function, etc.

It is declarative, that defines what needs to


be done, rather than how things need to be PL/SQL is procedural that defines how the
done. things needs to be done.

Execute as a single statement. Execute as a whole block.

Mainly used to manipulate data. Mainly used to create an application.

It is an extension of SQL, so it can contain


Cannot contain PL/SQL code in it. SQL inside it.
Structure of PL/SQL Block:

PL/SQL extends SQL by adding constructs found in procedural languages, resulting


in a structural language that is more powerful than SQL. The basic unit in PL/SQL is
a block. All PL/SQL programs are made up of blocks, which can be nested within
each other.

Typically, each block performs a logical action in the program. A block has the
following structure:
DECLARE
declaration statements;

BEGIN
executable statements

EXCEPTIONS
exception handling statements

END;
 Declare section starts with DECLARE keyword in which variables, constants,
records as cursors can be declared which stores data temporarily. It basically
consists definition of PL/SQL identifiers. This part of the code is optional.
 Execution section starts with BEGIN and ends with END keyword.This is a
mandatory section and here the program logic is written to perform any task like
loops and conditional statements. It supports all DML commands, DDL commands
and SQL*PLUS built-in functions as well.
 Exception section starts with EXCEPTION keyword.This section is optional
which contains statements that are executed when a run-time error occurs. Any
exceptions can be handled in this section.

PL/SQL identifiers

There are several PL/SQL identifiers such as variables, constants, procedures, cursors,
triggers etc.
1. Variables:
Like several other programming languages, variables in PL/SQL must be
declared prior to its use. They should have a valid name and data type as well.
Syntax for declaration of variables:
variable_name datatype [NOT NULL := value ];
Example to show how to declare variables in PL/SQL :

SQL> SET SERVEROUTPUT ON;

SQL> DECLARE

var1 INTEGER;

var2 REAL;

var3 varchar2(20) ;

BEGIN

null;

END;

/
Every PL/SQL statement ends with a semicolon (;). PL/SQL blocks can be nested
within other PL/SQL blocks using BEGIN and END. Following is the basic structure of
a PL/SQL block −
DECLARE
<declarations section>
BEGIN
<executable command(s)>
EXCEPTION
<exception handling>
END;

The 'Hello World' Example


DECLARE
message varchar2(20):= 'Hello, World!';
BEGIN
dbms_output.put_line(message);
END;
/
The end; line signals the end of the PL/SQL block. To run the code from the SQL
command line, you may need to type / at the beginning of the first blank line after the
last line of the code. When the above code is executed at the SQL prompt, it produces
the following result −
Hello World

PL/SQL procedure successfully completed.

The PL/SQL Identifiers


PL/SQL identifiers are constants, variables, exceptions, procedures, cursors, and
reserved words. The identifiers consist of a letter optionally followed by more letters,
numerals, dollar signs, underscores, and number signs and should not exceed 30
characters.
By default, identifiers are not case-sensitive. So you can use integer or INTEGER to
represent a numeric value. You cannot use a reserved keyword as an identifier.

The PL/SQL Delimiters


A delimiter is a symbol with a special meaning. Following is the list of delimiters in
PL/SQL −

Delimiter Description
+, -, *, / Addition, subtraction/negation, multiplication, division

% Attribute indicator

' Character string delimiter

. Component selector

(,) Expression or list delimiter

: Host variable indicator

, Item separator

" Quoted identifier delimiter

= Relational operator

@ Remote access indicator

; Statement terminator

:= Assignment operator

=> Association operator

|| Concatenation operator

** Exponentiation operator
<<, >> Label delimiter (begin and end)

/*, */ Multi-line comment delimiter (begin and end)

-- Single-line comment indicator

.. Range operator

<, >, <=, >= Relational operators

<>, '=, ~=, ^= Different versions of NOT EQUAL

The PL/SQL Comments


Program comments are explanatory statements that can be included in the PL/SQL
code that you write and helps anyone reading its source code. All programming
languages allow some form of comments.
The PL/SQL supports single-line and multi-line comments. All characters available
inside any comment are ignored by the PL/SQL compiler. The PL/SQL single-line
comments start with the delimiter -- (double hyphen) and multi-line comments are
enclosed by /* and */.
DECLARE
-- variable declaration
message varchar2(20):= 'Hello, World!';
BEGIN
/*
* PL/SQL executable statement(s)
*/
dbms_output.put_line(message);
END;
/
When the above code is executed at the SQL prompt, it produces the following result −
Hello World

PL/SQL procedure successfully completed.


PL/SQL - Data Types
PL/SQL Scalar Data Types and Subtypes
PL/SQL Scalar Data Types and Subtypes come under the following categories −

S.No Date Type & Description

1 Numeric
Numeric values on which arithmetic operations are performed.

2 Character
Alphanumeric values that represent single characters or strings of characters.

3 Boolean
Logical values on which logical operations are performed.

4 Datetime
Dates and times.

PL/SQL provides subtypes of data types. For example, the data type NUMBER has a
subtype called INTEGER. You can use the subtypes in your PL/SQL program to make
the data types compatible with data types in other programs while embedding the
PL/SQL code in another program, such as a Java program.

PL/SQL Numeric Data Types and Subtypes


Following table lists out the PL/SQL pre-defined numeric data types and their sub-
types −

S.No Data Type & Description

NUMBER(prec, scale)
1
Fixed-point or floating-point number with absolute value in range 1E-130 to (but not
including) 1.0E126. A NUMBER variable can also represent 0
2 DEC(prec, scale)
ANSI specific fixed-point type with maximum precision of 38 decimal digits

3 DECIMAL(prec, scale)
IBM specific fixed-point type with maximum precision of 38 decimal digits

4 NUMERIC(pre, scale)
Floating type with maximum precision of 38 decimal digits

FLOAT
5
ANSI and IBM specific floating-point type with maximum precision of 126 binary
digits (approximately 38 decimal digits)

6 INT
ANSI specific integer type with maximum precision of 38 decimal digits

7 INTEGER
ANSI and IBM specific integer type with maximum precision of 38 decimal digits

8 SMALLINT
ANSI and IBM specific integer type with maximum precision of 38 decimal digits

REAL
9
Floating-point type with maximum precision of 63 binary digits (approximately 18
decimal digits)

DECLARE
num1 INTEGER;
num2 REAL;
num3 DOUBLE PRECISION;
BEGIN
null;
END;
When the above code is compiled and executed, it produces the following result −
PL/SQL procedure successfully completed

PL/SQL Character Data Types and Subtypes


Following is the detail of PL/SQL pre-defined character data types and their sub-types

S.No Data Type & Description

1 CHAR
Fixed-length character string with maximum size of 32,767 bytes

2 VARCHAR2
Variable-length character string with maximum size of 32,767 bytes

RAW
3
Variable-length binary or byte string with maximum size of 32,767 bytes, not
interpreted by PL/SQL

4 NCHAR
Fixed-length national character string with maximum size of 32,767 bytes

5 NVARCHAR2
Variable-length national character string with maximum size of 32,767 bytes

6 LONG
Variable-length character string with maximum size of 32,760 bytes

LONG RAW
7
Variable-length binary or byte string with maximum size of 32,760 bytes, not
interpreted by PL/SQL
8 ROWID
Physical row identifier, the address of a row in an ordinary table

PL/SQL Date time and Interval Types


The DATE data type is used to store fixed-length date times, which include the time of
day in seconds since midnight. Valid dates range from January 1, 4712 BC to
December 31, 9999 AD.
The default date format is set by the Oracle initialization parameter
NLS_DATE_FORMAT. For example, the default might be 'DD-MON-YY', which
includes a two-digit number for the day of the month, an abbreviation of the month
name, and the last two digits of the year. For example, 01-OCT-12.
Each DATE includes the century, year, month, day, hour, minute, and second. The
following table shows the valid values for each field −

Field Name Valid Datetime Values Valid Interval Values

YEAR -4712 to 9999 (excluding year 0) Any nonzero integer

MONTH 01 to 12 0 to 11

01 to 31 (limited by the values of MONTH


DAY and YEAR, according to the rules of the Any nonzero integer
calendar for the locale)

HOUR 00 to 23 0 to 23

MINUTE 00 to 59 0 to 59

00 to 59.9(n), where 9(n) is the precision of 0 to 59.9(n), where 9(n) is the


SECOND time fractional seconds precision of interval fractional
seconds

TIMEZONE_HOUR -12 to 14 (range accommodates daylight Not applicable


savings time changes)

PL/SQL Large Object (LOB) Data Types


Large Object (LOB) data types refer to large data items such as text, graphic images,
video clips, and sound waveforms. LOB data types allow efficient, random, piecewise
access to this data. Following are the predefined PL/SQL LOB data types −

Data Type Description Size

Used to store large binary objects in operating System-dependent. Cannot


BFILE
system files outside the database. exceed 4 gigabytes (GB).

Used to store large binary objects in the 8 to 128 terabytes (TB)


BLOB
database.

Used to store large blocks of character data in 8 to 128 TB


CLOB
the database.

Used to store large blocks of NCHAR data in 8 to 128 TB


NCLOB
the database.

PL/SQL User-Defined Subtypes


A subtype is a subset of another data type, which is called its base type. A subtype has
the same valid operations as its base type, but only a subset of its valid values.
PL/SQL predefines several subtypes in package STANDARD. For example, PL/SQL
predefines the subtypes CHARACTER and INTEGER as follows −
SUBTYPE CHARACTER IS CHAR;
SUBTYPE INTEGER IS NUMBER(38,0);
You can define and use your own subtypes. The following program illustrates defining
and using a user-defined subtype −
DECLARE
SUBTYPE name IS char(20);
SUBTYPE message IS varchar2(100);
salutation name;
greetings message;
BEGIN
salutation := 'Reader ';
greetings := 'Welcome to the World of PL/SQL';
dbms_output.put_line('Hello ' || salutation || greetings);
END;
/
When the above code is executed at the SQL prompt, it produces the following result −
Hello Reader Welcome to the World of PL/SQL

PL/SQL procedure successfully completed.

NULLs in PL/SQL
PL/SQL NULL values represent missing or unknown data and they are not an
integer, a character, or any other specific data type. Note that NULL is not the same as
an empty data string or the null character value '\0'. A null can be assigned but it
cannot be equated with anything, including itself.
PL/SQL programming language allows to define various types of variables, such as
date time data types, records, collections, etc. which we will cover in subsequent
chapters. For this chapter, let us study only basic variable types.

Variable Declaration in PL/SQL


PL/SQL variables must be declared in the declaration section or in a package as a
global variable. When you declare a variable, PL/SQL allocates memory for the
variable's value and the storage location is identified by the variable name.
The syntax for declaring a variable is −
variable_name [CONSTANT] datatype [NOT NULL] [:= | DEFAULT
initial_value]

Where, variable_name is a valid identifier in PL/SQL, datatype must be a valid PL/SQL


data type or any user defined data type which we already have discussed in the last
chapter. Some valid variable declarations along with their definition are shown below −
sales number(10, 2);
pi CONSTANT double precision := 3.1415;
name varchar2(25);
address varchar2(100);
When you provide a size, scale or precision limit with the data type, it is called
a constrained declaration. Constrained declarations require less memory than
unconstrained declarations. For example −
Sales number (10, 2);
Initializing Variables in PL/SQL
Whenever you declare a variable, PL/SQL assigns it a default value of NULL. If you
want to initialize a variable with a value other than the NULL value, you can do so
during the declaration, using either of the following −
 The DEFAULT keyword
 The assignment operator
For example −
counter binary_integer := 0;
greetings varchar2(20) DEFAULT 'Have a Good Day';
You can also specify that a variable should not have a NULL value using the NOT
NULL constraint. If you use the NOT NULL constraint, you must explicitly assign an
initial value for that variable.
It is a good programming practice to initialize variables properly otherwise, sometimes
programs would produce unexpected results. Try the following example which makes
use of various types of variables −
DECLARE
a integer := 10;
b integer := 20;
c integer;
f real;
BEGIN
c := a + b;
dbms_output.put_line('Value of c: ' || c);
f := 70.0/3.0;
dbms_output.put_line('Value of f: ' || f);
END;
/
When the above code is executed, it produces the following result −
Value of c: 30
Value of f: 23.333333333333333333

PL/SQL procedure successfully completed.

Variable Scope in PL/SQL


PL/SQL allows the nesting of blocks, i.e., each program block may contain another
inner block. If a variable is declared within an inner block, it is not accessible to the
outer block. However, if a variable is declared and accessible to an outer block, it is
also accessible to all nested inner blocks. There are two types of variable scope −
 Local variables − Variables declared in an inner block and not accessible to
outer blocks.
 Global variables − Variables declared in the outermost block or a package.
Following example shows the usage of Local and Global variables in its simple form −
DECLARE
-- Global variables
num1 number := 95;
num2 number := 85;
BEGIN
dbms_output.put_line('Outer Variable num1: ' || num1);
dbms_output.put_line('Outer Variable num2: ' || num2);
DECLARE
-- Local variables
num1 number := 195;
num2 number := 185;
BEGIN
dbms_output.put_line('Inner Variable num1: ' || num1);
dbms_output.put_line('Inner Variable num2: ' || num2);
END;
END;
/
When the above code is executed, it produces the following result −
Outer Variable num1: 95
Outer Variable num2: 85
Inner Variable num1: 195
Inner Variable num2: 185

PL/SQL procedure successfully completed.

Assigning SQL Query Results to PL/SQL Variables


You can use the SELECT INTO statement of SQL to assign values to PL/SQL
variables. For each item in the SELECT list, there must be a corresponding, type-
compatible variable in the INTO list. The following example illustrates the concept. Let
us create a table named CUSTOMERS −
(For SQL statements, please refer to the SQL tutorial)
CREATE TABLE CUSTOMERS(
ID INT NOT NULL,
NAME VARCHAR (20) NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR (25),
SALARY DECIMAL (18, 2),
PRIMARY KEY (ID)
);

Table Created
Let us now insert some values in the table −
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Ramesh', 32, 'Ahmedabad', 2000.00 );

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


VALUES (2, 'Khilan', 25, 'Delhi', 1500.00 );

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


VALUES (3, 'kaushik', 23, 'Kota', 2000.00 );

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


VALUES (4, 'Chaitali', 25, 'Mumbai', 6500.00 );

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


VALUES (5, 'Hardik', 27, 'Bhopal', 8500.00 );

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


VALUES (6, 'Komal', 22, 'MP', 4500.00 );
The following program assigns values from the above table to PL/SQL variables using
the SELECT INTO clause of SQL −
DECLARE
c_id customers.id%type := 1;
c_name customers.name%type;
c_addr customers.address%type;
c_sal customers.salary%type;
BEGIN
SELECT name, address, salary INTO c_name, c_addr, c_sal
FROM customers WHERE id = c_id;
dbms_output.put_line
('Customer ' ||c_name || ' from ' || c_addr || ' earns ' ||
c_sal);
END;
/
When the above code is executed, it produces the following result −
Customer Ramesh from Ahmedabad earns 2000

PL/SQL procedure completed successfully


Name varchar2(25);
address varchar2(100);

Declaring a Constant
A constant is declared using the CONSTANT keyword. It requires an initial value and
does not allow that value to be changed. For example −
PI CONSTANT NUMBER: = 3.141592654;
DECLARE
-- constant declaration
pi constant number := 3.141592654;
-- other declarations
radius number(5,2);
dia number(5,2);
circumference number(7, 2);
area number (10, 2);
BEGIN
-- processing
radius := 9.5;
dia := radius * 2;
circumference := 2.0 * pi * radius;
area := pi * radius * radius;
-- output
dbms_output.put_line('Radius: ' || radius);
dbms_output.put_line('Diameter: ' || dia);
dbms_output.put_line('Circumference: ' || circumference);
dbms_output.put_line('Area: ' || area);
END;
/
When the above code is executed at the SQL prompt, it produces the following result −
Radius: 9.5
Diameter: 19
Circumference: 59.69
Area: 283.53

Pl/SQL procedure successfully completed.


PL/SQL - Conditions
PL/SQL programming language provides following types of decision-making
statements. Click the following links to check their detail.

S.No Statement & Description

IF - THEN statement

1
The IF statement associates a condition with a sequence of statements enclosed
by the keywords THEN and END IF. If the condition is true, the statements get
executed and if the condition is false or NULL then the IF statement does nothing.

IF-THEN-ELSE statement
2
IF statement adds the keyword ELSE followed by an alternative sequence of
statement. If the condition is false or NULL, then only the alternative sequence of
statements get executed. It ensures that either of the sequence of statements is
executed.

IF-THEN-ELSIF statement
3
It allows you to choose between several alternatives.

Case statement

Like the IF statement, the CASE statement selects one sequence of statements to
4 execute.
However, to select the sequence, the CASE statement uses a selector rather than
multiple Boolean expressions. A selector is an expression whose value is used to
select one of several alternatives.

nested IF-THEN-ELSE
5
You can use one IF-THEN or IF-THEN-ELSIF statement inside another IF-
THEN or IF-THEN-ELSIF statement(s).

PL/SQL - Loops
PL/SQL provides the following types of loop to handle the looping requirements. Click
the following links to check their detail.

S.No Loop Type & Description

PL/SQL Basic LOOP

1
In this loop structure, sequence of statements is enclosed between the LOOP and
the END LOOP statements. At each iteration, the sequence of statements is
executed and then control resumes at the top of the loop.

PL/SQL WHILE LOOP


2
Repeats a statement or group of statements while a given condition is true. It tests
the condition before executing the loop body.
PL/SQL FOR LOOP
3
Execute a sequence of statements multiple times and abbreviates the code that
manages the loop variable.

Nested loops in PL/SQL


4
You can use one or more loop inside any another basic loop, while, or for loop.

Labeling a PL/SQL Loop


PL/SQL loops can be labeled. The label should be enclosed by double angle brackets
(<< and >>) and appear at the beginning of the LOOP statement. The label name can
also appear at the end of the LOOP statement. You may use the label in the EXIT
statement to exit from the loop.
The following program illustrates the concept −
DECLARE
i number(1);
j number(1);
BEGIN
<< outer_loop >>
FOR i IN 1..3 LOOP
<< inner_loop >>
FOR j IN 1..3 LOOP
dbms_output.put_line('i is: '|| i || ' and j is: ' || j);
END loop inner_loop;
END loop outer_loop;
END;
/
When the above code is executed at the SQL prompt, it produces the following result −
i is: 1 and j is: 1
i is: 1 and j is: 2
i is: 1 and j is: 3
i is: 2 and j is: 1
i is: 2 and j is: 2
i is: 2 and j is: 3
i is: 3 and j is: 1
i is: 3 and j is: 2
i is: 3 and j is: 3

PL/SQL procedure successfully completed.


The Loop Control Statements
Loop control statements change execution from its normal sequence. When execution
leaves a scope, all automatic objects that were created in that scope are destroyed.
PL/SQL supports the following control statements. Labeling loops also help in taking
the control outside a loop. Click the following links to check their details.

S.No Control Statement & Description

EXIT statement
1
The Exit statement completes the loop and control passes to the statement
immediately after the END LOOP.

CONTINUE statement
2
Causes the loop to skip the remainder of its body and immediately retest its
condition prior to reiterating.

GOTO statement
3
Transfers control to the labeled statement. Though it is not advised to use the
GOTO statement in your program.

PL/SQL - Arrays
In this chapter, we will discuss arrays in PL/SQL. The PL/SQL programming language
provides a data structure called the VARRAY, which can store a fixed-size sequential
collection of elements of the same type. A varray is used to store an ordered collection
of data, however it is often better to think of an array as a collection of variables of the
same type.
All varrays consist of contiguous memory locations. The lowest address corresponds to
the first element and the highest address to the last element.

An array is a part of collection type data and it stands for variable-size arrays. We will
study other collection types in a later chapter 'PL/SQL Collections'.
Each element in a varray has an index associated with it. It also has a maximum size
that can be changed dynamically.

Creating a Varray Type


A varray type is created with the CREATE TYPE statement. You must specify the
maximum size and the type of elements stored in the varray.
The basic syntax for creating a VARRAY type at the schema level is −
CREATE OR REPLACE TYPE varray_type_name IS VARRAY (n) of
<element_type>
Where,

 varray_type_name is a valid attribute name,


 n is the number of elements (maximum) in the varray,
 element_type is the data type of the elements of the array.
Maximum size of a varray can be changed using the ALTER TYPE statement.
For example,
CREATE Or REPLACE TYPE namearray AS VARRAY(3) OF VARCHAR2(10);
/

Type created.
The basic syntax for creating a VARRAY type within a PL/SQL block is −
TYPE varray_type_name IS VARRAY(n) of <element_type>
For example −
TYPE namearray IS VARRAY(5) OF VARCHAR2(10);
Type grades IS VARRAY(5) OF INTEGER;
Let us now work out on a few examples to understand the concept −

Example 1

The following program illustrates the use of varrays −


DECLARE
type namesarray IS VARRAY(5) OF VARCHAR2(10);
type grades IS VARRAY(5) OF INTEGER;
names namesarray;
marks grades;
total integer;
BEGIN
names := namesarray('Kavita', 'Pritam', 'Ayan', 'Rishav',
'Aziz');
marks:= grades(98, 97, 78, 87, 92);
total := names.count;
dbms_output.put_line('Total '|| total || ' Students');
FOR i in 1 .. total LOOP
dbms_output.put_line('Student: ' || names(i) || '
Marks: ' || marks(i));
END LOOP;
END;
/
When the above code is executed at the SQL prompt, it produces the following result −
Total 5 Students
Student: Kavita Marks: 98
Student: Pritam Marks: 97
Student: Ayan Marks: 78
Student: Rishav Marks: 87
Student: Aziz Marks: 92

PL/SQL procedure successfully completed.

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.No Parts & Description

Declarative Part
1 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.

3 Exception-handling
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.No Parameter Mode & Description

IN
An IN parameter lets you pass a value to the subprogram. It is a read-only
1 parameter. 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
3 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.
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.


PL/SQL - Functions
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.


PL/SQL - Cursors
A cursor is a pointer to this context area. PL/SQL controls the context area through a
cursor. A cursor holds the rows (one or more) returned by a SQL statement. The set of
rows the cursor holds is referred to as the active set.
You can name a cursor so that it could be referred to in a program to fetch and process
the rows returned by the SQL statement, one at a time. There are two types of cursors

 Implicit cursors
 Explicit cursors

Implicit Cursors
Implicit cursors are automatically created by Oracle whenever an SQL statement is
executed, when there is no explicit cursor for the statement. Programmers cannot
control the implicit cursors and the information in it.
Whenever a DML statement (INSERT, UPDATE and DELETE) is issued, an implicit
cursor is associated with this statement. For INSERT operations, the cursor holds the
data that needs to be inserted. For UPDATE and DELETE operations, the cursor
identifies the rows that would be affected.
In PL/SQL, you can refer to the most recent implicit cursor as the SQL cursor, which
always has attributes such as %FOUND, %ISOPEN, %NOTFOUND,
and %ROWCOUNT. The SQL cursor has additional
attributes, %BULK_ROWCOUNT and %BULK_EXCEPTIONS, designed for use with
the FORALL statement. The following table provides the description of the most used
attributes −

S.No Attribute & Description

%FOUND
1 Returns TRUE if an INSERT, UPDATE, or DELETE statement affected one or
more rows or a SELECT INTO statement returned one or more rows. Otherwise, it
returns FALSE.

%NOTFOUND
2 The logical opposite of %FOUND. It returns TRUE if an INSERT, UPDATE, or
DELETE statement affected no rows, or a SELECT INTO statement returned no
rows. Otherwise, it returns FALSE.

%ISOPEN
3
Always returns FALSE for implicit cursors, because Oracle closes the SQL cursor
automatically after executing its associated SQL statement.

%ROWCOUNT
4
Returns the number of rows affected by an INSERT, UPDATE, or DELETE
statement, or returned by a SELECT INTO statement.
Any SQL cursor attribute will be accessed as sql%attribute_name as shown below in
the example.

Example

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 will update the table and increase the salary of each customer
by 500 and use the SQL%ROWCOUNT attribute to determine the number of rows
affected −
DECLARE
total_rows number(2);
BEGIN
UPDATE customers
SET salary = salary + 500;
IF sql%notfound THEN
dbms_output.put_line('no customers selected');
ELSIF sql%found THEN
total_rows := sql%rowcount;
dbms_output.put_line( total_rows || ' customers selected ');
END IF;
END;
/
When the above code is executed at the SQL prompt, it produces the following result −
6 customers selected

PL/SQL procedure successfully completed.


If you check the records in customers table, you will find that the rows have been
updated −
Select * from customers;

+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2500.00 |
| 2 | Khilan | 25 | Delhi | 2000.00 |
| 3 | kaushik | 23 | Kota | 2500.00 |
| 4 | Chaitali | 25 | Mumbai | 7000.00 |
| 5 | Hardik | 27 | Bhopal | 9000.00 |
| 6 | Komal | 22 | MP | 5000.00 |
+----+----------+-----+-----------+----------+

Explicit Cursors
Explicit cursors are programmer-defined cursors for gaining more control over
the context area. An explicit cursor should be defined in the declaration section of the
PL/SQL Block. It is created on a SELECT Statement which returns more than one row.
The syntax for creating an explicit cursor is −
CURSOR cursor_name IS select_statement;
Working with an explicit cursor includes the following steps −

 Declaring the cursor for initializing the memory


 Opening the cursor for allocating the memory
 Fetching the cursor for retrieving the data
 Closing the cursor to release the allocated memory

Declaring the Cursor


Declaring the cursor defines the cursor with a name and the associated SELECT
statement. For example −
CURSOR c_customers IS
SELECT id, name, address FROM customers;

Opening the Cursor


Opening the cursor allocates the memory for the cursor and makes it ready for fetching
the rows returned by the SQL statement into it. For example, we will open the above
defined cursor as follows −
OPEN c_customers;

Fetching the Cursor


Fetching the cursor involves accessing one row at a time. For example, we will fetch
rows from the above-opened cursor as follows −
FETCH c_customers INTO c_id, c_name, c_addr;
Closing the Cursor
Closing the cursor means releasing the allocated memory. For example, we will close
the above-opened cursor as follows −
CLOSE c_customers;

Example

Following is a complete example to illustrate the concepts of explicit cursors &minua;


DECLARE
c_id customers.id%type;
c_name customer.name%type;
c_addr customers.address%type;
CURSOR c_customers is
SELECT id, name, address FROM customers;
BEGIN
OPEN c_customers;
LOOP
FETCH c_customers into c_id, c_name, c_addr;
EXIT WHEN c_customers%notfound;
dbms_output.put_line(c_id || ' ' || c_name || ' ' || c_addr);
END LOOP;
CLOSE c_customers;
END;
/
When the above code is executed at the SQL prompt, it produces the following result −
1 Ramesh Ahmedabad
2 Khilan Delhi
3 kaushik Kota
4 Chaitali Mumbai
5 Hardik Bhopal
6 Komal MP

PL/SQL procedure successfully completed.


A record is a data structure that can hold data items of different kinds. Records
consist of different fields, similar to a row of a database table.
For example, you want to keep track of your books in a library. You might want to track
the following attributes about each book, such as Title, Author, Subject, Book ID. A
record containing a field for each of these items allows treating a BOOK as a logical
unit and allows you to organize and represent its information in a better way.
PL/SQL can handle the following types of records −

 Table-based
 Cursor-based records
 User-defined records

Table-Based Records
The %ROWTYPE attribute enables a programmer to create table-
based and cursorbased records.
The following example illustrates the concept of table-based records. We will be using
the CUSTOMERS table we had created and used in the previous chapters −
DECLARE
customer_rec customers%rowtype;
BEGIN
SELECT * into customer_rec
FROM customers
WHERE id = 5;
dbms_output.put_line('Customer ID: ' || customer_rec.id);
dbms_output.put_line('Customer Name: ' || customer_rec.name);
dbms_output.put_line('Customer Address: ' ||
customer_rec.address);
dbms_output.put_line('Customer Salary: ' ||
customer_rec.salary);
END;
/
When the above code is executed at the SQL prompt, it produces the following result −
Customer ID: 5
Customer Name: Hardik
Customer Address: Bhopal
Customer Salary: 9000

PL/SQL procedure successfully completed.

Cursor-Based Records
The following example illustrates the concept of cursor-based records. We will be
using the CUSTOMERS table we had created and used in the previous chapters −
DECLARE
CURSOR customer_cur is
SELECT id, name, address
FROM customers;
customer_rec customer_cur%rowtype;
BEGIN
OPEN customer_cur;
LOOP
FETCH customer_cur into customer_rec;
EXIT WHEN customer_cur%notfound;
DBMS_OUTPUT.put_line(customer_rec.id || ' ' ||
customer_rec.name);
END LOOP;
END;
/
When the above code is executed at the SQL prompt, it produces the following result −
1 Ramesh
2 Khilan
3 kaushik
4 Chaitali
5 Hardik
6 Komal

PL/SQL procedure successfully completed.

User-Defined Records
PL/SQL provides a user-defined record type that allows you to define the different
record structures. These records consist of different fields. Suppose you want to keep
track of your books in a library. You might want to track the following attributes about
each book −

 Title
 Author
 Subject
 Book ID

Defining a Record

The record type is defined as −


TYPE
type_name IS RECORD
( field_name1 datatype1 [NOT NULL] [:= DEFAULT EXPRESSION],
field_name2 datatype2 [NOT NULL] [:= DEFAULT EXPRESSION],
...
field_nameN datatypeN [NOT NULL] [:= DEFAULT EXPRESSION);
record-name type_name;
The Book record is declared in the following way −
DECLARE
TYPE books IS RECORD
(title varchar(50),
author varchar(50),
subject varchar(100),
book_id number);
book1 books;
book2 books;

Accessing Fields

To access any field of a record, we use the dot (.) operator. The member access
operator is coded as a period between the record variable name and the field that we
wish to access. Following is an example to explain the usage of record −
DECLARE
type books is record
(title varchar(50),
author varchar(50),
subject varchar(100),
book_id number);
book1 books;
book2 books;
BEGIN
-- Book 1 specification
book1.title := 'C Programming';
book1.author := 'Nuha Ali ';
book1.subject := 'C Programming Tutorial';
book1.book_id := 6495407;
-- Book 2 specification
book2.title := 'Telecom Billing';
book2.author := 'Zara Ali';
book2.subject := 'Telecom Billing Tutorial';
book2.book_id := 6495700;

-- Print book 1 record


dbms_output.put_line('Book 1 title : '|| book1.title);
dbms_output.put_line('Book 1 author : '|| book1.author);
dbms_output.put_line('Book 1 subject : '|| book1.subject);
dbms_output.put_line('Book 1 book_id : ' || book1.book_id);

-- Print book 2 record


dbms_output.put_line('Book 2 title : '|| book2.title);
dbms_output.put_line('Book 2 author : '|| book2.author);
dbms_output.put_line('Book 2 subject : '|| book2.subject);
dbms_output.put_line('Book 2 book_id : '|| book2.book_id);
END;
/
When the above code is executed at the SQL prompt, it produces the following result −
Book 1 title : C Programming
Book 1 author : Nuha Ali
Book 1 subject : C Programming Tutorial
Book 1 book_id : 6495407
Book 2 title : Telecom Billing
Book 2 author : Zara Ali
Book 2 subject : Telecom Billing Tutorial
Book 2 book_id : 6495700

PL/SQL procedure successfully completed.

Records as Subprogram Parameters

You can pass a record as a subprogram parameter just as you pass any other variable.
You can also access the record fields in the same way as you accessed in the above
example −
DECLARE
type books is record
(title varchar(50),
author varchar(50),
subject varchar(100),
book_id number);
book1 books;
book2 books;
PROCEDURE printbook (book books) IS
BEGIN
dbms_output.put_line ('Book title : ' || book.title);
dbms_output.put_line('Book author : ' || book.author);
dbms_output.put_line( 'Book subject : ' || book.subject);
dbms_output.put_line( 'Book book_id : ' || book.book_id);
END;

BEGIN
-- Book 1 specification
book1.title := 'C Programming';
book1.author := 'Nuha Ali ';
book1.subject := 'C Programming Tutorial';
book1.book_id := 6495407;

-- Book 2 specification
book2.title := 'Telecom Billing';
book2.author := 'Zara Ali';
book2.subject := 'Telecom Billing Tutorial';
book2.book_id := 6495700;

-- Use procedure to print book info


printbook(book1);
printbook(book2);
END;
/
When the above code is executed at the SQL prompt, it produces the following result −
Book title : C Programming
Book author : Nuha Ali
Book subject : C Programming Tutorial
Book book_id : 6495407
Book title : Telecom Billing
Book author : Zara Ali
Book subject : Telecom Billing Tutorial
Book book_id : 6495700

PL/SQL procedure successfully completed.

PL/SQL - Exceptions
An exception is an error condition during a program execution. PL/SQL supports
programmers to catch such conditions using EXCEPTION block in the program and an
appropriate action is taken against the error condition. There are two types of
exceptions −

 System-defined exceptions
 User-defined exceptions

Syntax for Exception Handling


The general syntax for exception handling is as follows. Here you can list down as
many exceptions as you can handle. The default exception will be handled
using WHEN others THEN −
DECLARE
<declarations section>
BEGIN
<executable command(s)>
EXCEPTION
<exception handling goes here >
WHEN exception1 THEN
exception1-handling-statements
WHEN exception2 THEN
exception2-handling-statements
WHEN exception3 THEN
exception3-handling-statements
........
WHEN others THEN
exception3-handling-statements
END;

Example
Let us write a code to illustrate the concept. We will be using the CUSTOMERS table
we had created and used in the previous chapters −
DECLARE
c_id customers.id%type := 8;
c_name customerS.Name%type;
c_addr customers.address%type;
BEGIN
SELECT name, address INTO c_name, c_addr
FROM customers
WHERE id = c_id;
DBMS_OUTPUT.PUT_LINE ('Name: '|| c_name);
DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr);

EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('No such customer!');
WHEN others THEN
dbms_output.put_line('Error!');
END;
/
When the above code is executed at the SQL prompt, it produces the following result −
No such customer!

PL/SQL procedure successfully completed.


The above program displays the name and address of a customer whose ID is given.
Since there is no customer with ID value 8 in our database, the program raises the run-
time exception NO_DATA_FOUND, which is captured in the EXCEPTION block.

Raising Exceptions
Exceptions are raised by the database server automatically whenever there is any
internal database error, but exceptions can be raised explicitly by the programmer by
using the command RAISE. Following is the simple syntax for raising an exception −
DECLARE
exception_name EXCEPTION;
BEGIN
IF condition THEN
RAISE exception_name;
END IF;
EXCEPTION
WHEN exception_name THEN
statement;
END;
You can use the above syntax in raising the Oracle standard exception or any user-
defined exception. In the next section, we will give you an example on raising a user-
defined exception. You can raise the Oracle standard exceptions in a similar way.

User-defined Exceptions
PL/SQL allows you to define your own exceptions according to the need of your
program. A user-defined exception must be declared and then raised explicitly, using
either a RAISE statement or the
procedure DBMS_STANDARD.RAISE_APPLICATION_ERROR.
The syntax for declaring an exception is −
DECLARE
my-exception EXCEPTION;

Example

The following example illustrates the concept. This program asks for a customer ID,
when the user enters an invalid ID, the exception invalid_id is raised.
DECLARE
c_id customers.id%type := &cc_id;
c_name customerS.Name%type;
c_addr customers.address%type;
-- user defined exception
ex_invalid_id EXCEPTION;
BEGIN
IF c_id <= 0 THEN
RAISE ex_invalid_id;
ELSE
SELECT name, address INTO c_name, c_addr
FROM customers
WHERE id = c_id;
DBMS_OUTPUT.PUT_LINE ('Name: '|| c_name);
DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr);
END IF;

EXCEPTION
WHEN ex_invalid_id THEN
dbms_output.put_line('ID must be greater than zero!');
WHEN no_data_found THEN
dbms_output.put_line('No such customer!');
WHEN others THEN
dbms_output.put_line('Error!');
END;
/
When the above code is executed at the SQL prompt, it produces the following result −
Enter value for cc_id: -6 (let's enter a value -6)
old 2: c_id customers.id%type := &cc_id;
new 2: c_id customers.id%type := -6;
ID must be greater than zero!

PL/SQL procedure successfully completed.

Pre-defined Exceptions
PL/SQL provides many pre-defined exceptions, which are executed when any
database rule is violated by a program. For example, the predefined exception
NO_DATA_FOUND is raised when a SELECT INTO statement returns no rows. The
following table lists few of the important pre-defined exceptions −

Oracle
Exception SQLCODE Description
Error

It is raised when none of the choices in


the WHEN clause of a CASE statement
CASE_NOT_FOUND 06592 -6592
is selected, and there is no ELSE
clause.

It is raised when duplicate values are


DUP_VAL_ON_INDEX 00001 -1 attempted to be stored in a column with
unique index.

It is raised when attempts are made to


make a cursor operation that is not
INVALID_CURSOR 01001 -1001
allowed, such as closing an unopened
cursor.

It is raised when the conversion of a


character string into a number fails
INVALID_NUMBER 01722 -1722
because the string does not represent a
valid number.

It is raised when a program attempts to


LOGIN_DENIED 01017 -1017 log on to the database with an invalid
username or password.
It is raised when a SELECT INTO
NO_DATA_FOUND 01403 +100
statement returns no rows.

It is raised when a database call is


NOT_LOGGED_ON 01012 -1012 issued without being connected to the
database.

It is raised when PL/SQL has an


PROGRAM_ERROR 06501 -6501
internal problem.

It is raised when a cursor fetches value


ROWTYPE_MISMATCH 06504 -6504 in a variable having incompatible data
type.

It is raised when PL/SQL ran out of


STORAGE_ERROR 06500 -6500
memory or memory was corrupted.

It is raised when a SELECT INTO


TOO_MANY_ROWS 01422 -1422
statement returns more than one row.

It is raised when an arithmetic,


VALUE_ERROR 06502 -6502 conversion, truncation, or size
constraint error occurs.

It is raised when an attempt is made to


ZERO_DIVIDE 01476 1476
divide a number by zero.

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