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

Introduction To PL

PLSQL

Uploaded by

Maneesh Kumar
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
368 views

Introduction To PL

PLSQL

Uploaded by

Maneesh Kumar
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 117

Oracle

pl/sql programming
INTRODUCTION TO PL/SQL
CHAPTER I
PL/SQL ENGINE, BLOCKS, DATATYPES

PL/SQL first appeared in Oracle Version 6 in 1988. It was primarily


used within Oracles user interface product SQL Forms to allows for the inclusion
of complex logic within the forms. It replaced an old step method for logical
control and provided a reasonably simple programming language that resembled
ADA and C. Looking back at those days, we remember converting old Pro * C
programs into PL/SQL so that we could more easily maintain them. Actually, the
C programmer took another job, and we had lots of people who wanted to use
their new programming language knowledge. So we converted all the code in a
relatively short time frame, and here we are far ahead with some of that original
PL/SQL code still in use. We have come a long way since then. Today we use
PL/SQL to read data, to populate the database, create stored objects, and even
to display web pages. PL/SQL has certainly grown into a mature product. Oracle
has shown a strong dedication to the language, as illustrated by its use of
PL/SQL in many of its products, such as Oracle Applications. Oracle is also
using the web portion of PL/SQL quite extensively. Have you visited
www.oracle.com lately ? If so, you have seen PL/SQL for the web in action. So
lets move on and look more closely at the PL/SQL programming language.
It is Just as important to learn PL/SQL as it is to learn SQL. So,
whether you are looking at becoming a DBA or an Oracle developer , knowledge
of PL/SQL is a skill that you must have in your database toolkit. In this session
we will discuss the following:

Overview of PL/SQL structure


Components of PL/SQL
Compilation and execution
Block structure
Variables and datatypes
Execution control
Looping
SQL in PL/SQL
Cursors
Exceptions
Stored procedures and functions and Packages
Triggers

Terminology
1/117

Oracle

pl/sql programming

The following Terminology will arm you with the technical jargon to get through
this chapter.

A program is a set of commands that perform a specific task.


Variables are programmer defined names to store information while
running a program.
The declare section is where you define the variables in a program.
The executable section is where you define the steps that will run in the
program you create.
An exception is a system-or user-defined error- handling mechanism
within a program.
A data type defines the class of a piece of information or data. For
example, you can think of information n as numbers or characters. In
programming, the same is true- a character data type would contain any
set of characters, and a numeric data type would contain decimals
between 0 and 9 and may be either a positive or negative value.
A PL/SQL block is the set of commands that constitute a PL/SQL program.
An anonymous PL/SQL block that may contain a declare section, will
always contain an executable section, and may contain an exception
section. A named PL/SQL block is one that is defined and named for
storage in the database.
An executable is the name of a programs written using one of an
assortment of computer programming languages. When you type the
name of an executable, the program runs. For example, when you use
SQL *Plus you enter the command sqlplus.
Arithmetic operators are symbols used to define mathematical operations
performed on data. The most common operators are + (additional),(Subtraction), / (division)), * (multiplication.)
Relational operators define comparisons or choices made on data. For
example, if you wish to see whether two dates are equal, you would use
the relational operator. Some common relational operators are =(equal), >
(greater than), < (less than), != (not equal).
A loop is a construct in a computer program in which a segment of code is
executed repeatedly.
An exit condition is the part of the loop where a test is performed on data.
If the test returns a result of true, then you might exit the loop.
An array is a data set that may be held in a memory structure that can
hold many rows of information. You can usually move from row to row in
an array. It is a variable, but it is one that may contain more than one
value at any one time.
A cursor is an Oracle memory structure that holds an SQL statement and
may also hold the result during the running of a program.

2/117

Oracle

pl/sql programming
A stored object is a PL/SQL program that is saved in the database and
may be shared and used by many developers and end users. Procedures,
packages, functions, and triggers are all examples of stored objects.

PL/SQL: THE ORACLE PROGRAMMING LANGUAGE


The Oracle 9i Database is more than just a database. It is also an
engine for many languages. It serves as a java engine with the built-in java
Virtual Machine (JVM), as well as a PL/SQL engine. This means that the
code may be stored in the database and then run. So there is no need for
another product. The PL/SQL engine is bundled with the database. Imagine
a product from Oracle that works really well and is free. How can they make
any money ? Lets look at how PL/SQL fits in to the Oracle database. The
following Figure shows you how PL/SQL works from within and from outside
the database.

3/117

Oracle

pl/sql programming

ORACLE DATABASE

INTEGRATED SQL
INTEGRATED
ENGINE SQL
ENGINE

External
Program
calls

PL/SQL
Stored
Program

PL/SQL
PL/SQL
Engine
Engine
SQL
ENGINE
SQL
ENGINE

DATABASE

FIGURE: I PL/SQL architecture


In Figure1, you see at the center the oracle 9i Server, the primary
engine for the data base. It serves as the coordinator for all calls to the
database. When a call is made from a program to the server to run a PL/SQL
program, the database (Oracle) loads the compiled program into memory,
and then the PL/SQL engine and SQL engine execute the program. The
PL/SQL engine will handle the programs memory structures and logical
program flow. The SQL engine then issues data requests to the database. It
is a closed system and one that allows for very efficient programming.
PL/SQL is used in numerous Oracle products, including :

4/117

Oracle

pl/sql programming

The Oracle server


Oracle forms
Oracle Reports
Oracle Warehouse Builder
Oracle Applications
Oracle Portal

All these programs use PL/SQL to some extent. There may be as


many as 5 million lines of Pl/SQL code contained in Oracle Applications, for
example. PL/SQL program can be called from these Oracle development
environments:

SQL *Plus
Oracle Enterprise Manager
Oracle precompilers (such as Pro *C, Pro *COBOL, etc.)
Oracle Call Interface (OCI)
Server Manager
Oracle 9i Application Server
Java Virtual Machine (JVM)
As you can see, PL/SQL is well established within most of
the Oracle9i line of products. You may now have some background in the
Pl/SQL architecture. Lets discover the basics of the language.
PL/SQL CHARACTER SET
As with all programming languages, there are characters
that you use to write your programs. Each language has its own rules and
restrictions when it comes to the valid characters. In the following
sections, we will learn the following:

Valid characters when programming in PL/SOL


Arithmetic operators
Relational operators

Supported Characters
When programming in PL/SQL, you may only use characters as
defined here:

Upper-or lowercase characters


All digits between 0 and 9
5/117

Oracle

pl/sql programming

Symbols: ( ) + -*/<>=!~;:.-@%,#^&_|{ }?[ ]


Some of these characters are for program commands; others serve
as relation or arithmatic operators. Together they form a program.
Arithmetic Operators and Relational Operators
Table I shows the common arithematic operators and Table 2 shows the
commom relational operators used in PL/SQL. They are listed in the order
that they are executed (known as precedence, or priority). When the
functions appear in the same line, this means they are executed with the
same level of precedence, so the position of the expression will decide which
goes first.

Table I - Common Mathematical Operators


Operator

Meaning

**
*, /

Exponent
Multiplication,
division
+, - , ||
Addition, subtraction,
concatenation.

Table 2 - Common Relational Operators


Operator
=
<> or !=
>
<
>=
<=

Meaning
Equal
Not equal
Greater than
Less than
Greater than or equal
Less than or equal

6/117

Oracle

pl/sql programming

PL/SQL STRUCTURE
The structure used in all of PL/SQL is the foundation for all of
the language. When you master it, you will be able to move forward, but
if you do not take the time to get this first step right, your journey will be
difficult. Actually, it is easy, Lets look at the structure that all of your
Pl/SQL programs will have.
You will have areas for program parameters (used to pass values from
outside a program to the program), internal variables, the main program
code and logic, and then some ways to handle things when they go
wrong.
PL/SQL BLOCK STRUCTURE
A basic PL/SQL block of code can contain up to three parts. The order in
which the sections of the blocks are written is shown below:Section

Description

Inclusion

Declarative

Contains all variables,


constants, cursors, and
user-defined exceptions
that will be referenced
within the Executable
section.

Optional

7/117

Oracle

Note:

pl/sql programming
Executable

Contains SQL statements


to manipulate data in the
database and PL/SQL
statements to manipulate
data in the block.

Mandatory

Exception
Handling

Specifies the actions to


perform when errors and
abnormal conditions arise
within the Executable
section.

Optional

In PL/SQ, an error or warning is called an exception.

- Section keywords DECLARE, BEGIN, and EXCEPTION are not


followed by semicolons. However, END and all other PL/SQL statements do
require a semicolon to terminate the statement. You can string statements
together on the same line. However, this method is not recommended for
clarity or editing.

8/117

Oracle

pl/sql programming
PL/SQL block structure

DECLARE -Optional
-Variables,constants,
cursors,user-defined exceptions
BEGIN -Mandatory
-SQL Statements
-PL/SQL control statements
EXCEPTION -Optional
-Actions to perform when errors occur.
END; - Mandatory

PL/SQL Block Structure


Every unit of PL/SQL comprises one or more blocks. These blocks
can be entirely separate or nested one within another. Therefore, one block can
represent a small part of another block, which in turn can be part of the whole
unit of code.

PL/SQL Program constructs


The following list outlines a variety of different PL/SQL program
constructs using the basic PL/SQL block. They are available based on the
environments where they are executed
Program Construct
Anonymous Block

Description
Unnamed PL/SQL block
that is embedded within

9/117

Availability
All PL/SQL environments.

Oracle

Stored Procedure or
Function
Application Procedure or
Function
Package

Database Trigger

Application Trigger

pl/sql programming
an application or is
issued interactively.
Named PL/SQL block
that can accept
parameters and can be
invoked repeatedly.
Named PL/SQL block
that can accept
parameters and can be
invoked repeatedly.
Named PL/SQL module
that groups together
related procedures,
functions, and identifiers.
PL/SQL block that is
associated with a
database table and is
fired automatically.
PL/SQL block that is
associated with an
application even and it
fired automatically.

Oracle Server with


Procedural Extension.
Components of
Developer/2000, for
example forms.
Oracle Server with
procedural Extension.
Oracle Server with
Procedural Extension.
Components of
Developer/2000, for
example Forms.

Note: A function is similar to a procedure, except that a function must return a


value.
The two types of constructs covered in this course are anonymous
blocks and subprograms.
Anonymous Blocks
Anonymous blocks are un-named blocks. They are declared at the
point in an application where they are to be executed and are passed to the
PL/SQL engine for execution at runtime. You can embed an anonymous block
within a precompiler program and within SQL* Plus or server Manager. Triggers
in Developer/2000 components consist of such blocks.
Subprograms
Subprograms are named Pl/SQL blocks. You can declare them
either as procedures or as functions. Procedure perform actions and functions
return values.
10/117

Oracle

pl/sql programming

Developer/2000 components allow you to declare procedures and functions as


part of the application (a form or report), and call them from other procedures,
functions, and triggers.

BLOCK TYPES
Anonymous
[DECLARE]
BEGIN
--statements;

Procedure

Function

PROCEDURE name
IS

FUNCTION name
IS
BEGIN

BEGIN

--statements

--statements

RETURN value;

[EXCEPTION]

[EXCEPTION]

[EXCEPTION]
END;
END;

END;

PL/SQL VARIABLES AND DATATYPE


You will almost always need to use variables in a PL/SQL program. It is here that
you will define how your data is to be held , while you work it through your
program.

11/117

Oracle

pl/sql programming

Handling Variables in PL/SQL


Declare and initialize variables within the declarative section
Assign new values to variables within the executable section
Pass values into PL/SQL blocks through parameters
View results through output variables.

Delcaring PL/SQL Variables and Constants.


You need to declare all identifiers within the declaration section
before referencing them within the PL/SQL block.
Syntax
Identifier [ Constant ] datatype [ Not Null ]
[ := | DEFAULT expr ] ;
WHERE:
IDENTIFIER
CONSTANT
DATATYPE

- is the name of the identifier


- Constrains the identifier so that its
value cannot change; constant
must be initialized.
- Is a scalar or composite datatype

NOT NULL

- Constrains the variable so that it


must contain a value; NOT NULL
variables must be initialized

EXPR

- Is any PL/SQL expression that can


be a literal, another variable, or an
expression involving operators and
functions.

Guidelines

Name the identifier according to the same rules used for SQL objects
You can use naming conventions, for example v_name to represent a
variable, and c_name to represent a constant.

12/117

Oracle

pl/sql programming

You have the option of assigning an initial Value to variables, unless they are
NOT NULL.
Initialize the variable to an expression with the assignment operator (:=) or
equivalently, with the DEFAULT reserved word: otherwise, variables are
initialized to NULL by default.
Declare at most one identifier per line.

PL/SQL supports three datatypes - scalar, composite and


reference that you can use for declaring variables, constants and pointers.

Scalar Data types


A scalar data type holds a single value and has no internal
components. Scalar data types can be classified into four categories:

Number
Character
date and time
Boolean

Character and number data types have subtypes that associate a


base type to a constraint. For example, INTEGER and POSITIVE are subtypes
of the NUMBER base type.

Datatype
BINARY-INTEGER
NUMBER(Precision-scale)
CHAR (Maximumlength)
LONG
VARCHAR2(maximum-length)
DATE
BOOLEAN

Description
Base type for integers between
2147483647 and 2147483647.
Base type for fixed and floating point
numbers.
Base type for fixed length character data
up to 32767 bytes. If you do not specify
a maximum length, the default length is
set to 1.
Base type for variable length character
data upto 32760 bytes.
Base type for variable length character
data up to 32767 bytes.
Base type for dates and times.
Base type that stores one of three
possible values used for logical
13/117

Oracle

pl/sql programming
calculations: TRUE,FALSE, or NULL.
Scalar Variable Declarations: Examples

V_gender
V_count
V_total_sal
V_order_date
C_tax_rate
V_valid

CHAR(1);
BINARY_INTEGER := 0;
NUMBER(9,2) := 0;
DATE := SYSDATE + 7;
CONSTANT NUMBER(3,2) := 8.25;
BOOLEAN NOT NULL := TRUE;

Declaring Scalar Variables


Examples
1. Declare a variable to store the gender code (M or F)
V_gender
CHAR (1);
2. Declare a variable to count the iterations of a loop and intialize the variable to
0
V_count

- BINARY-INTEGER :=0;

3. Declare a variable to accumulate the total salary for a department and initialize
the variable to 0
V_total_sal

NUMBER (9,2) :=0 ;

4. Declare a variable to store the ship date of an order, and initialize the variable
to one week from today.
V_order_date DATE := SYSDATE + 7;
5. Declare a constant for the tax rate, which never changes throughout the
PL/SQL block.
C_tax_rate CONSTANT NUMBER (3,2) := 8.25;

14/117

Oracle

pl/sql programming

6. Declare a flag to indicate whether a piece of data is valid or invalid, and


initialize the variable to TRUE.
V_valid

BOOLEAN NOT NULL : =TRUE;

The %Type Attribute

The % TYPE Attribute


Declare a variable according to

- Another previously declared variable


- A database column definition.
Prefix %Type with
-The database table and column
-The previously declared variable name.
-PL/SQL determines the datatype and size of the variable.

When you declare PL/SQLvariables to hold column values, you


must ensure that the variable is of the correct datatype and precision. If it is not,
then a PL/SQL error will occur during the execution.
Rather than hard-coding the datatype and precision of a variable,
you can declare a variable according to another previously-declared variable or
data base column. You do this using the % TYPE attribute. To use the attribute
15/117

Oracle

pl/sql programming

in place of the datatype required in the variable declaration, prefix it with the
database table and column names. If referring to a previously declared variable,
prefix the variable name to the attribute.
PL/SQL determines the datatype and size of the variable when
the block is compiled. So the variable is always compatiable with the database
column or identifier used to populate the variable.
Advantages of Using the %TYPE Attribute
The datatype of the underlying database column may be unknown.
The datatype of the underlying database column may change at runtime.
Examples
1. Declare variables to store the first and last names for an employee.
DECLARE
V_last_name
V_first_name

s_emp.lastname%TYPE;
s_emp.first_name%TYPE;

2. Declare variables to store the balance for a checking account, as well as


the minimum balance, which starts out as 10.

DECLARE
V_balance
NUMBER (7,2);
V_minimum_balance v_balance%TYPE := 10;
A NOT NULL column constraint does not apply to variables
declared using %TYPE. Therefore, if you declare a
variable using the % TYPE attribute, using a database
column defined as NOT NULL, you can assign the NULL
value to the variable.
DECLARING COMPOSITE DATATYPES
Declaring Records with the %ROWTYPE Attribute

16/117

Oracle

pl/sql programming
The % ROWTYPE Attribute
Declare a variable according to a collection of columns in a
database table or view.
Prefix %ROWTYPE with the database table.
Fields within the RECORD take their names and datatypes from
the columns of the table or view.

Declaring a record based upon a collection of columns in a


database table or view by using the % ROWTYPE attribute.
The fields within the record take their names and datatypes
from the columns of the table or view.

You declare records in the DECLARE section of a block, along with the
other types of variables you have seen.

Advantages of Using the %ROWTYPE Attribute


The number and datatypes of the underlying database columns may be
unknown.
The number and datatypes of the underlying database columns may
change at runtime.
The structure is the same as the cursor or the database table. Especially
useful when retrieving a row with the SELECT statement, or when
retrieving multiple rows with an explicit cursor.
Example
Declare a variable to store the same information about a department as it is
stored in the S_DEPT table.

Dept_record
Emp_record

DECLARE
s_dept%ROWTYPE;
s_emp%ROWTYPE;

17/117

Oracle

pl/sql programming

This declaration creates a record with the same field names and field
datatypes as a row in a table. DEPT_RECORD is a record. The fields
are: DEPT_RECORD.ID, DEPT_RECORD.NAME and
DEPT_RECORD.REGION_ID
Referencing Non-PL/SQL Variables

Referencing Non-PL/SQL Variables


Reference non- PL/SQLvariables as host variables.
Prefix the reference with a colon ( : )

You can reference variables declared in the host or calling environment


in PL/SQL statements, unless the statement is within a procedure,
function, or package. This includes host language variables declared
in precompiler programs. Screen fields in a Developer/2000 Forms
application, and SQL*Plus bind variables.
To reference host variables, you must prefix the references with a
colon ( : ) to distinguish them from declared PL/SQL variables.
Example
Store the annual salary in a SQL *Plus global variable.
:g_annual_salary := v_salary *12;

18/117

Oracle

pl/sql programming
CHAPTER 2
CONTROL STRUCTURES, EXCEPTIONS, TRIGGERS
AND CURSOR

CONTROL STRUCTURES
At the heart of any programming language are its control structures.
Since Programs are written to handle a number of different situations, the
manner in which different conditions are detected and dealt with is the biggest
part of program control. Various types of control structures are used for this
purpose, including
If logic structures
Case expressions
Looping structures
Program control is governed by the status of variables and the data
that is read from and written to the database. As an example, picture yourself
going into the drivers license office to renew your drivers license. When you
enter the officer, you are presented with a number of directional signs. One sign
reads Driver Testing ; for this, you go to the second floor. Another sign tells you
that License Renewals is one the third floor. You are here for a renewal, so you
head up to the third floor. Once you arrive in the renewal office, you are once
again faced with some new choices. Now you have to decide whether you are
going to pay by cash or credit card. Cash payments are being accepted to the
right, and credit cards are to the left. You see that you have enough cash, and
you head to the payment wicket on the right. Let us look at Table below and see
how our program control influenced your choices.

step process or decision to make


1
2
3
4
5
6
7
8
9

next steps

here for a driverss license yes=2 no=4


here is for driving test
yes=5 no=3
here for a license renewal
yes=6 no=4
ask for help
right place=1 wrong=13
go to second floor
7
go to third floor
9
line up for test
8
pass test
6
payment method
cash=10 credit=11
19/117

Oracle

pl/sql programming

10
cash payment wicket
12
11
credit card payment
12
receive new license
13
13
go home leave building
-------------------------------------------------------------------------------------------------TABLE- Program Control Decision Matrix
IF Logic Structures
When you are writing computer programs, situations present
themselves in which you must test a condition. When you ask a question
in your program, you are usually presented with one of two answers; it
may be true or it may be false. Computer programs are black and white;
in computer logic, there can only be true or false answers to your
questions, no maybe. PL/SQL provides you with three distinctive if logic
structures that allows you to test for true and false conditions. In everyday
life we are presented with decisions that we need to make; the following
sections will show you how to do it using PL/SQL.
IF - THEN
You use the if-then construct to test the simplest type of
condition. If the condition evaluates to true, then one or more lines of
program code will be executed. If the condition evaluates as false, then
no action is taken. The following code snippet illustrates how this is
performed with a PL/SQL program.
IF I_date > 11-APR-03 then
I_salary := I_salary * 1.15;
- - Increase salary by 15%
END IF:
NOTE:

Each IF statement is followed by its own then. There is


also no semicolon ( ; ) terminator on a line that begins with
an IF.

To add comments to your code, start a comment line with /*


and end with */ or you may use the double hyphen ( - -) as
we have done in the above example.

20/117

Oracle

pl/sql programming
In this case, if the value of the variable I_date is greater than
11th of April 2003, then the salary will be increased by 15 percent . This
statement may also be restated using the following statement.
IF not (I_date <= 11 APR-03) then
I_salary := I_salary *1.15;
-- Increase salary by 15%
END IF;
Also, you nest IF _ THEN statement to increase the power
of your statements. Let us add a condition to limit who gets the raise:
IF I_date > 11-Apr-03 then
IF I_last _name = PAKMAN then
I_salary := 1-salary *1.15 ;
-- Increase salary by 15%
END IF;
END IF:
Now, not only must the date be greater than the 11th of April ,
2003, but also your last name must be equal to Pakman in order to get the
raise. This a method that we use to make sure human resource programs
give programmers a raise every year.
What you should also notice in this code is that there are now two end if
statements. This is a required construct, since you must always pair an if
statement with an end if; so if you are going to have nested if statements,
you must ensure that each is paired with a matching end if;
NOTE

Each IF statement block must have at least one line of program


code. If you wish to do nothing within your program code, simply
use the NULL; command.

IF - THEN ELSE
The if-then-else construct is similar to the simple if-then
construct. The difference is that when the condition executes as false , the
program statements that follow the else statement are executed. The
following code illulstrated this logic within PL/SQL.
IF I_date > 11-APR-03 then
I_salary := I_salary *1.15 ;
-- Increase salary by 15%
ELSE
I_salary := I_salary *1.05 ;
21/117

Oracle

pl/sql programming
--Increase salary by 5%
END IF;
In the preceding code listing, you see the condition that if the
date is greater than the 11th of april, 2003, you will get a 15 percent salary
increase. However, when the date is less than or equal to this date, you
will only receive a 5 percent increase.
As with the simple if-then construct, you may nest the ifthen-else construct. Let us look at how this might appear in our PL/SQL
program:
IF I_date > 11-Apr-03 then
IF I_last_name = PAKMAN then
I_salary := I_salary *1.15;
-- Increase salary by 15%
ELSE
I_salary := I_salary *1.10;
-- Increase salary by 10%
END IF;
ELSE
I_salary := I_salary *1.05;
-- Increase salary by 5%
END IF;

This leads us to another note on using the if statement within


PL/SQL

NOTE:
- Only one else statement is allowed within every if statement construct,
and there is no semicolon(;) on the line starting with else.
IF THEN - ELSIF
The final if construct that we will show you is if-then-elsif. In
this case, you provide yourself with the option to test another condition
when the first condition is evaluated as false. When you want to test for
more than one condition without using nested if statements, this is the type
of statement that you might use.
IF I_last__name = PAKMAN then
I_salary := I_salary *1.15;
-- Increase salary by 15%
ELSIF I_last_name = ASTROFF then
I_salary := I_salary *1.10;
22/117

Oracle

pl/sql programming
-- Increase salary by 10%
ELSE
I_salary := I_salary *1.05;
-- Increase salary by 5%
END IF;
In the preceding statement, if your last name is Pakman, you
get a 15 percent raise; if it is Astroff, you get 10 percent; and the rest of us
get only a 5 per cent raise. There is no limit to the number of elsif
conditions that you may use within this construct. The following shows
you an example of using multiple elsif statement within the construct.
IF I_city = OTTAWA then
L_team_name := SENATORS;
ELSIF I_city = LOS ANGELS then
L_team_name := KINGS;
ELSIF I_city = NEW YORK then
L_team _name := RANGERS;
ELSIF I_city = TORONTO then
L_team_name := MAPLE LEAFS;
END IF;

NOTE:
There is no matching END IF statement for each elsif. Only a single
END IF is required within this construct.
When writing your PL/SQL program, use indentation to simplify the
reading of the program, as in the code segments shown here. As a rule ,
you should line up each if-then-else statement, and indent the program
code that lies between each of these words.

CASE EXPRESSIONS
The next logical step from the if statement is the case
statement. The case statement, which was introduced with Oracle 9i, is
an evolution in logical control. It differs from the if-then-else constructs in
that you now can use a simple structure to logically select from a list of
values. More important, it may be used to set the value of a variable. Let
us look at how this may be done. First, let us look at the format:

23/117

Oracle

pl/sql programming
CASE variable
WHEN expressional then value 1
WHEN expression 2 then value 2
WHEN expression 3 then value 3
WHEN expression 4 then value 4
ELSE value 5
END;

There is no limit to the number of expressions that may be


defined in a case expression. Here is an example of the use of
the case expression:

SQL>run
1 DECLARE
2 val varchar2(100) ;
3 city varchar2 (20) := TORONTO;
4 BEGIN
5 val := CASE city
6 WHEN TORONTO then RAPTORS
7 WHEN LOS ANGELS then LAKERS
8 WHEN BOSTON then CELTICS
9 WHEN CHICAGO then BULLS
10 ELSE NO TEAM
11 END;
12
13 dbms_ouput.put_line (val);--output to the screen
14 * end;
15 RAPTORS
PL/SQL procedure successfully completed.
NOTE:

In order to get oracle to provide ouput from a PL/SQL program,


you must set the environment variable within SQL* Plus. To do
this, type as follows:
SET serveroutput on

Although you can use the if-then-else to achieve the same


purpose, the case statement is easier to read and more efficient.
24/117

Oracle

pl/sql programming
Remember that once Oracle 9i reaches a value in the case statement that
meets the condition, the processing of the case statement will stop.
LOOPS
Loops are control structures that allow you to repeat a set of
commands until you decide that it is time to stop the looping.
Generally, the format that all loops take is the flowing:
LOOP
Executable statements;
END LOOP;
Each time the loop is executed, the statements within the loop are
executed, and then the program return to the top of the loop structure to
do it all over again. However, if you ever want this processing to stop,
you will need to learn about the EXIT statement.
The exist statement allows you to stop executing within a loop
without a condition. It will then pass control back to the program and will
continue on after the loop statements.
The following is how to get out of a tight loop:
LOOP
IF I_batting_average <= 300 then EXIT;
ELSE
L_decision := STAY IN MAJORS;
END IF;
END LOOP;
There are many other kinds of loops that provide more
control over looping. Each has its uses in PL/SQL programming, and each
should be learned so that you have maximum flexibility in your
programming needs.

25/117

Oracle

pl/sql programming
The while Loop
The while loop will continue to execute as long as the condition that you
have defined continues to be true. If the condition becomes false, then
you exit the loop. Let us look at an example.
WHILE I_sales_total < 100000 LOOP
SELECT sales_amount INTO
I_sale_amount
FROM daily_sales;
I_sales_total := I_sales_total + I_sale_amount;
END LOOP;

Although you may use the exist command to do the same thing.
It is better form to use the while expression.

The for Loop


The for loop is one of the most common loops that you will
encounter in your PL/SQL travels. This loop allows you to control the
number of times that a loop executes.In the case of the while loop, you are
never quite sure how many times a loop is executed, since it will continue
to loop until a codition is met. The for loop allows you to define the
number of times that you will be looping when you program the loop itself.
You will define the value to start your loop with and the value that will
terminate your loop. Let us look at some syntax;
FOR I_counter IN 1 .. 10
LOOP
Statements;
END LOOP;
So, what is important for you to note in the preceding
statement? First, you need to know that the variable I_counter will hold
the value between 1 and 10. How do we know it will be between 1 and 10
? Well, after the IN, we place the counters range. In this case, the
counter starts at I, the low bound, and continues to 10. You should also
note the two dots. (..) between the two integer values (1 and 10). This tells
Oracle 9i that you would like it to count between these two numbers.
One more note:

regardless of any previous values that the variable I_counter has


been set to in an earlier command in your program, when you

26/117

Oracle

pl/sql programming
use the values in the loop, you will discover that they are now
set to values between 1 and 10.
-

You can also count backward using the REVERSE clause.


The next code listing shows you how the reverse clause
may be used.

DECLARE
I_counter number;
BEGIN
FOR I_counter IN REVERSE 1..5
LOOP
Dbms_output.put_line (I_counter);
END LOOP;
End;
/
5
4
3
2
1
PL/SQL procedure successfully completed.

Now you can see how easy it is to use simple loops, but loops have
much more power. Using loops like the while loop or the for loop allows you to
use variables instead of hard coded values. This gives you the greatest possible
flexibility because you can have the database or external data provide you with
the limits within your loop. Let us look at how this might work. In the following
example, we select the number of employees in our employee table, and then
show how the counter counts from 1 to the number of employees in our small
company.
SQL>run
1 DECLARE
2 I_emp_count number;
3 i number ; -- We will use this as our counter
4
BEGIN
5
select the number of employees in the
I_emp_count variable
6 Select count (*) into I_emp_count from employees;
7
8
FOR i IN 1 .. I_emp_count LOOP
27/117

--

Oracle

pl/sql programming
9 dbms_output.put_line (Employee || i);
10
END LOOP;
11 *END;

Employee 1
Employee 2
Employee 3
Employee 4
Employee 5
Employee 6
PL/SQL procedure successfully completed.
- As you might have guessed, we have six employees in our company. (It
may be small, but it is very good.) The important point is that you may use
variables in your loops. The other line that you may have noticed is the select
statement contained in this PL/SQL block. You might be thinking, what are
they talking about and where did this come from ? Well, we have not told you
about select statements in your Pl/SQL programs, but this seems like a
perfect time to talk about SQL in your PL/SQL programs.
SQL in Your PL/SQL Programs
We have looked at a lot of structure up until now. You should know that a
PL/SQL program will always have a BEGIN and END. It may have variables ,
loops, or logic control, but your next question must be wheres the best ?
What gives PL/SQL its beef is SQL. Since you have all these CONTROL
structures, you need to use them in conjunction with information.You may
want the information
so that you can create a report, update data, create
new data,and delete old data, or perform just about any other function that
you can think of. It is very important for you to see how you can integrate
data into PL/SQL code. Without data, PL/SQL is just PL.

28/117

Oracle

pl/sql programming
EXCEPTIONS

INTRODUCTION
When you execute PL/SQL program, you may encounter errors, that stop
the program. Any well-written program must have the ability to handle such
errors intelligently and recover from them , if possible. PL/SQL implements error
handling via exceptions and Exception Handlers which can be associated with
oracle errors or with user defined errors. In this chapter, we wll discuss the
types of exceptions, how exceptions are raised and handled, association of
exceptions with ORACLE error and the rule of the exception propogation. It also
provides the guidelines on using exceptions.
We already know how PL/SQL is based on the ADA language. One of the
features of ADA that is incorporated into PL/SQL is the exception mechanism,
that makes your programs robust and able to deal with both unexpected and
expected errors during execution.
What kinds of error can occur in a PL/SQL Program ?
Errors can be classified as compile-time and run-time errors. Compiletime errors are reported by PL/SQL compiler interactivelty & you have to correct
them. Without correcting them PL/SQL wll not run at all.
So exceptions are designed for runtime error handling only, rather than
compile time error handling.
WHAT IS EXCEPTION?
An exception is an identifier in PL/SQL which is raised when an error occurs,
during the execution of a block. This terminates its main body of actions and
transfers control to a separate program called exception handler , which specifies
the final action to be performed. This separates the error handling from the rest
of the program which makes the logic of the program, easier to understand.
This also ensures that all errors will be trapped.
In a language (such as C) that does not use the exception model for error
handling , you must explicitly insert error handling code in order to ensure that
your program can handle errors , in all cases.
For example
Int x,y,z;
Function(x); /* function call, passing x as an argument */

29/117

Oracle

pl/sql programming

If < an error occurred >


Handle_error ();
Y = 1/z;
Handle_error(.);
Z = x+y;
Handle_error ();
Note that a check for errors must occur after each statement in the
program. If you forget to insert the check, the program will not properly
handle an error situation. In addition, the error handling can clutter up
the program, making it difficult to understand the programs logic.
The preceding example can be simplified in PL/SQL as follows:
DECLARE
X
NUMBER;
Y
NUMBER;
Z
NUMBER;
BEGIN
Function(x);
Y = 1/z;
Z = X+Y;
EXCEPTION
When OTHERS then
/* handler to execute all errors */
handle_error(.);
END;
Note that the error handling code is separated from the programs
logic. This solves problems occurring in the previous case.

Programs logic is easier to understand, since it is clearly visible.


No matter which statement fails, the programs will detect and handle the
error.

TRAPPING EXCEPTIONS:
Generally exceptions are declared in the declarative section of the block,
raised in the executable section and handled in the exception section.
PL/SQL provides a set of system defined exceptions and allows you to
add user defined exceptions.
There are 3 types of exceptions. They are as follows.

30/117

Oracle

pl/sql programming

1.

PREDEFINED ORACLE SERVER ERROR:


This is one of approximately 20 most common SQL errors that occur often
in PL/SQL program, which are defined in the package STANDARD . This
package is available to any PL/SQL block. So this exception need not be
declared. They are also raised automatically when the associated ORACLE
error occurs. Only they need to be handled in the exception handling section.
2.

NON PREDEFINED ORACLE-SERVER ERROR


Any other standard ORACLE server error falls in this category . Declare
this exception within the declarative section, and allow the ORACLE server to
raise them implicitly.
3.

USER DEFINED ERROR


A condition that the developer determines is abnormal, can be defined by
the program as a user_defined exception. It could be an error with the data
also. Declare it with the declarative section, raise and handle it explicitly.

The system_defined exceptions are as follows:

CURSOR_ALREADY_OPEN: Raised if an open statement tries to open a


cursor that is already open. You must close a cursor before you can reopen
it. SQL CODE is set to -6511 (error is ORA-06511)
INVALID_CURSOR:
Raised if you attempted to open an undeclared
cursor, or close, one that was not opened or fetch from one that was not
open, and so on. SQLCODE is set to -1001 (error is ORA-01001).
INVALID_NUMBER:
Raised on a conversion error from a character string
to a number, when the character string does not contain a legitimate number
in a SQL statement. SQL CODE is set to 1722. (error is ORA-01722)
LOGIN_DENIED:
Raised if user tries to logon to ORACLE with
an invalid username/ password. SQLCODE is set to -1017 (error is 0RA01017.)
DUP_VAL_ON_INDEX:
Raised if an insert or update would have
caused a duplicate value in unique database column. SQLCODE is set to 1
(error is ORA-00001).
NO_DATA_FOUND :
Raised if a select statement returns nothing.
SQLCODE is set to- +100 (error is ORA-01403)
TOO_MANY_ROWS: Raised when select statement that is supposed to
return just one row , returns more than one (this is also raised by a subquery
that is only supposed to return one row). SQL CODE is set to 1422 (error is
ORA-01422)
NOT_LOGGED_ON:
Raised if you attempt any sort of database call
without being logged on to ORACLE. SQLCODE is set to-1012 (error is
ORA-01012.)

31/117

Oracle

pl/sql programming

PROGRAM_ERROR: Raised if PL/SQL itself has an internal problem


executing the code such as exiting a function that has no return statement.
SQLCODE is set to - 6501 (ERROR IS ORA -06501)
STORAGE _ERROR; Raised if PL/SQL needs more memory than is
available that is run out of memory or memory is corruputed. SQLCODE is
set to 6500 (error is ORA-06500)
TIMEOUT_ON_RESOURCE: Raised when a time out occurs while ORACLE
is waiting for a resource. This usually means an instance has had an
abnormal termination. SQLCODE is set to -51 (error is ORA-00051)
TRANSACTION_BACKED_OUT:
Raised when the remote part of a
transaction is rolled back due to deadlock or data might be inconsistent at
some node. SQLCODE is set to - 61 (error is ORA-00061)
VALUE_ERROR:
Raised when the value of a column of PL/SQL is
damaged by arithematic, conversion, truncation or constraint error occurs in a
procedural statement. If the error occurs in a SQL statement,
INVALID_NUMBER is raised instead. SQLCODE is set to 6502 (error is
ORA-01456)
ZERO_DIVIDE: Raised when a statement tries to divide a number by zero.
SQLCODE is set to - 1476 (error is ORA-01476)

DECLARING,RAISING & HANDLING EXCEPTIONS:


1.
DECLARING EXCEPTIONS:
User defined & ORACLE non
predefined exceptions are declared in the declarative section as follows:
SYNTAX:
Exception_name EXCEPTION;
Where exception_name is the name of the exception and EXCEPTION
is the keyword for declaring exception.
2.
RAISING EXCEPTION:
When the error associated with an exception
occurs, the exception must be raised. User defined exceptions are raised
explicitly within the executable section using RAISE statement. Predefined
exceptions are raised automatically when their associated ORACLE error occurs.
For e.g. if the error ORA-01403 occurs when no rows are retrieved from the
database, the PL/SQL raises the exception NO_DATA_FOUND.

SYNTAX:
RAISE exception_name;

32/117

Oracle

pl/sql programming
Where exception_name is the name of the previously defined
exception.

3.
HANDLING EXCEPTIONS:
Reference the declared exception within
the corresponding exception handling routine using WHEN CLAUSE.
WHEN exception_name THEN
Statements;
Where exception_name is the name of the exception declared in the
declarative section and raised in the exevutable section.
EXAMPLE FOR USER DEFINED EXCEPTION:
DECLARE
e_invalid_staffno EXCEPTION;
BEGIN
IF &&p_staffno IS NULL OR
(TO_NUMBER (&p_staffno)
NOT BETWEEN 1000 ND 9999
THEN
RAISE e_invalid_staffno;
ELSE
INSERT INTO emp_data (staffno,emp_name, deptno)
VALUES (&p_staffno, &p_name, &p_deptno);
INSERT INTO emp_sal (staffno)
VALUES (&p_staffno);
END IF;
EXCEPTION
WHEN e_invalid _staffno THEN
INSERT INTO MESSAGE
VALUES (INVALID STAFF NUMBER, Staff number: || &p_staffno ||
must be between 1001 and 9999 );
END;
/
EXPLANATION: In the above example e_invalid_staffno is defined as an
exception in the declarative section by the user. In the executable section the
verification of staff number i.e. whether it is within the range 1001 -9999 is
33/117

Oracle

pl/sql programming

verified by the IF. ..END IF clause. If it is not, the exception e_invalid_staffno is


raised and control is transferred to the corresponding exception handling section
and a message is inserted into the table message.
Examples for pre defined exceptions:

Example for INVALID NUMBER

INSERT INTO emp_data


VALUES (ABCD,Kaimal, SDE, 10-Jan-50,TVM,10);
DECLARE
V_sl
V_Staffno
V_name
V_desgn
V_hq

NUMBER (2);
CHAR (4);
varchar2(25);
varchar2(5);
CHAR(3);

BEGIN
SELECT TO_NUMBER(staff no) -1000 as SL_NO, staffno,
Emp_name,desgn, hq
INTO v_sl,v_staffno, v_desgn, v_hq
FROM emp_data
WHERE staffno = ABCD;
INSERTINTO message
VALUES (to_char (v_sl) || - || v_staffno,
v_name || || desgn || - ||v_hq);
EXCEPTION
WHEN INVALID_NUMBER THEN
INSERT INTO Message
VALUES (invalid number, There is a wrong character value in the staff
number);
END;
/
Now execute the program and see the resultas follows:
SQL>SELECT *FROM MESSAGE;
OUTPUT:
INVALID NUMBER There is a wrong character value in the staff number.
34/117

Oracle

pl/sql programming

Explnation:
The staffno ABCD is converted to a number by the TO_NUMBER
function in the SQL statement. But since abcd cannot be converted
into a number, the exception INVALID_NUMBER is raised and action
is taken accordingly.
Example for DUP_VAL_ON_INDEX:
DECLARE
BEGIN
INSERT INTO emp_data (staffno, emp_name, deptno)
VALUES (&p_staffno, &P_name, &p_deptno);
Insert into EMP_SAL(staffno)
Values (&p_staffno);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
INSERT INTO MESSAGE
VALUES(DUP_VAL_ON_INDEX,
STAFFNO || &p_sattno || already exists);
END;
EXPLANATION:
When you try to insert a new row with the existing staff no,
DUP_VAL_ON_INDEX is raised and action is taken accordingly.
Example for NO_DATA_FOUND AND TOO_MANY_ROWS:
DECLARE
V_basic
V_name
V_desgn

emp_sal.basic%TYPE;
emp_data.emp_name%TYPE;
emp_data.desgn%TYPE;

BEGIN
SELECT emp_name,desgn INTO
V_name,v_desgn
FROM emp_data
WHERE staffno = &&_staffno;
Select basic INTO v_basic
FROM emp-sal
WHERE staffno = &p_staffno;
35/117

Oracle

pl/sql programming

INSERT INTO PAYBILL(Staffno,emp_name,desgn,basic)


VALUES (&p_staffno,v_name,v_desgn,v_basic);
EXCEPTION
When NO_DATA_FOUND THEN
INSERT INTO MESSAGE
VALUES (NO_DATA_FOUND,
There is no record of information for this staff no: || &p_staffno);
WHEN TOO MANY_ROWS THEN
INSERT INTO MESSAGE
VALUES (TOO_MANY_ROWS,
There are more than 1 records for this staff number : || &p_staffno);
END;
//
EXPLATION:
When there is no record under the given staffno in
EMP_DATA table, no row is returned by the SQL statement and so
NO_DATA_FOUND exception is raised and action is taken accordingly . When
there are more than 1 record for the given staffno in EMP_SAL table, more than
one row is retrieved by the 2ndSQL statement and so TOO_MANY_ROWS
exception is raised and action is taken accordingly.
EXAMPLE FOR VALUE_ERROR:
Both of the following examples raise VALUE_ERROR.
Example I :
DECLARE
Tempvar

varchar2(3);

BEGIN
Tempvar := ABCD;
EXCEPTION
WHEN VALUE _ERROR THEN
INSERT INTO message
VALUES (VALUE_ERROR,
There is an error in the assignment of value to the variable);
36/117

Oracle

pl/sql programming

END;
/
Example 2:
DECLARE
Tempvar

varchar2(3);

BEGIN
SELECT staffno
INTO tempvar
FROM emp_data
WHERE staffno = 1001 ;
EXCEPTION
WHEN VALUE_ERROR THEN
INSERT INTO message
VALUES (VALUE_ERROR,
There is an error in the assignment of value to the variable);
END;
/
EXPLANATION: The error can occur either as a result of an assignment
statement or selectinto statement.
EXAMPLE FOR ZERO_DIVIDE:
DECLARE
V_maxbasic NUMBER(6);
V_MINBASIC
NUMBER(6);
V_ratio
NUMBER(5,2)
BEGIN
SELECT MAX(basic), MIN(basic)
Into v_maxbasic, v_minbasic
FROM emp_sal;
V_ratio := v_maxbasic / v_minbasic;
INSERT INTO message

37/117

Oracle

pl/sql programming
VALUES (NULL ,
The ratio between maximum and minimum basicpay is ||
to_char(v_ratio));

EXCEPTION
WHEN ZERO_DIVIDE THEN
INSERT INTO message
VALUES (ZERO_DIVIDE ERROR,
There is zero value in the basicpay);
END;
/
Now execute the program and see the result as follows
SQL>SELECT * FROM message;
OUTPUT
The ratio between maximum and minimum basic pay is x.xx (some value).
Next modify one of the basic as 0 as follows:
SQL> UPDATE emp_sal
SET basic = 0
WHERE staffno = 1001;
Again run the program and observe the result.
OUTPUT:
ZERO_DIVIDE ERROR: There is zero value in the basic pay, so when an
attempt made to divide a number by zero, the ZERO_DIVIDE exception is raised
automatically and since there was a handler in the exception section, the control
branched there and recorded the error by inserting one row in the message table.
THE EXCEPTION_INIT PRAGMA:
The standard system exceptions, such as ZERO_DIVIDE which are
referenced by name, are no more than the association of a name with the
internal ORACLE error number. There are 100s of these error numbers, and
only the most common dozen have been given names. Any that are not named
will still raise exception flag and transfer control to the EXCEPTION block, but
they will all be caught by OTHERS rather than by name.

38/117

Oracle

pl/sql programming

You can change this by assigning your own names to other ORACLE error
number. This provides named exceptions in addition to the predefined ones.
EXCEPTION_INIT allow you to do this. Exception is the one word name you
assign to the integer error number. Integer should be negative if the error code
is negative (TRUE for fatal errors) and exception must follow normal object
naming rules.
Note that the syntax of this command requires the word PRAGMA
before EXCEPTION_INIT.
A PRAGMA is not an executable code. It is a compiler directive-an
instruction to the compiler, which can be thought of as a parenthetical remark to
the compiler. PRAGMAS (also called pesudoinstructions are processed at
compile time and not at run time. The predefined PRAGMA EXCEPTION_INIT
tells the PL/SQL compiler to associate an exception name with an ORACLE
error number. That allows you to refer to any internal exception by name and to
write a specific handler for it.
SYNTAX;
1.
Declare the name for the exception within the declarative section as
follows:
Exception_name EXCEPTION;
Where exception_name is the name of the exception.
2.
Associate the declared exception with standard ORACLE error number
using PRAGMA EXCEPTION_UNIT Statement in the declarative part of PL/SQL
block, sub-program or package.
PRAGMA EXCEPTION_INIT (exception_name,error-number):
Where exception_name is the name of the previously declared exception.
The PRAGMA must appear somewhere after the exception declaration in the
same declarativepart.
3.
Refer declared exception within the corresponding exception handling
routine.
Example:
The ORACLE error that is UNIQUE or NOT NULL CONSTRAINT
violated can be associated with an exception name empty_name as follows:
DECLARE

39/117

Oracle

pl/sql programming
/* ORACLE NON PREDEFINED EXCEPTION */
empty_name EXCEPTION;
PRAGMA EXCEPTION_INIT (empty_name, -1400);

BEGIN
INSERT INTO emp_data (staffno, emp_name, deptno) VALUES
(&p_staffno, &p_name, &p_deptno);
INSERT INTO emp_sal (staffno)
VALUES (&p_staffno);
EXCEPTION
WHEN empty_name THEN
INSERT INTO message
Values (Blank Name,
Employees name cannot be blank);
END;
/
SELECT * FROM Message;
Similarly, The referential integrity constraint violated which is having code
-2292 & The table or view does not exist, having code 942 can be associated
with an exception name using PRAGMA EXCEPTION_INIT.
CUSTOMISING ERROR CONDITIONS:
You may establish different error conditions within procedural objects. For
each of the error conditions you define, you may select an error message that will
appear when the error occurs by using built in fuction
RAISE_APPLICATION_ERROR to create your own message, which can be
more descriptive than named exceptions. This procedure is defined in the
STANDARD package and may be called from within any procedural object.
The syntax of the RAISE_APPLICATION_ERROR I:
RAISE_APPLICATION_ERROR (error_number, error_message,
[Keep_errors] ;
It takes three I/P parameters: the error number (which must be between
-20001 and 20999) and the error message which is the text to be displayed and
keep_errors : a Boolean value which is optional. If keep_errors is true, the new
error is added to the list of already raised (if one exists). If it is false , which is the
40/117

Oracle

pl/sql programming

default, the new error will replace the current list of errors. You get to assign both
the message number and the text that will be displayed to the user
EXAMPLE:
PROCEDURE paycalc(p_staffno IN emp_data.staffno%TYPE)
IS
Zero_pay EXCEPTION;
BEGIN

EXCEPTION
WHEN TOO_ MANY_ ROWS THEN
RAISE_APPLICATION_ERROR (-20001,
There are more than I records for this staff number : || p_staffno);
WHEN zero_pay THEN
RAISE_APPLICATION_ERROR(-20002,
Basic pay zero seems incorrect, It needs updation);
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-2003,
There is no record of information for this staff no: || p_staffno);
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-2004,
Some other error has occurred);
END paycalc;
In the above program RAISE_APPLICATION_ERROR procedure is called
from each exception handling section to give customized error messages by
setting the error numbers and messages via this procedure. Thus the use of the
RAISE_APPLICATION_ERROR procedure give you great flexibility in managing
the error conditions that may be encountered within your trigger / procedure.
This is a very powerful addition to the standard exceptions that are available in
PL/SQL .
EXCEPTION PROPOGATION:
Exception can occur in the declarative,executable or the exception
section of a PL/SQL block. We have seen what happens when exceptions are
raised in the executable portion of the block, when there is a handler for the
exception. But what, if there is no handler, or the exception is raised from

41/117

Oracle

pl/sql programming

different section of the block? The process that governs this is known as
exception propogation.
1.

Exception raised in the executable section:

When an exception is raised in the executable section of a block,


PL/SQL uses the following algorithm to determine which exception handler to
invoke.

If the current block has a handler for the exception, execute it and complete
the block successfully. Control then passes to the enclosing block.
If there is no handler for the current exception, propogate the exception by
raising it in the enclosing block. Step I will then be executed for the enclosing
block.
Before we can examine this algorithm in detail, we need to define an
enclosing block. A block can be embedded inside another block. In this case,
the outer block encloses the inner block.
EXAMPLE:
DECLARE
--Begin outer block

BEGIN
--Begin inner block. This is embedded in the outer block.
BEGIN

END;
.
BEGIN
--Begin inner block 2. This is also embedded in the
-- outer block.
--Note that this block does not
-- have a declarative part

END;
.
..
--End out block
END;

42/117

Oracle

pl/sql programming

In the preceding listing, inner blocks 1 and 2 are both enclosed by the
outer block. Any unhandled exceptions in block 1 and block 2 will be
propogated to the outer block.
A procedure call will also create an enclosing block, and is
illustrated in the following example:
BEGIN
--Begin outer block.
--call a procedure. The procedure will be enclosed by the
--outer block.
F()
END;
If procedure function raises an unhandled exception, it will be
propogated to the outer block, since it encloses the procedure.

TRIGGERS
INTRODUCTION
Like procedures, functions and packages. Triggers are named PL/SQL blocks
with declarative, executable and exception handling sections. Like packages,
Triggers must be stored in the database and cannot be local to a block .
However a procedure is executed explicitly from another block which can pass
arguments. But a trigger is executed implicitly, whenever the triggering event
happens and a trigger does not accept arguments. The act of executing a
trigger is known as firing the trigger. The triggering event is a DML (INSERT,
UPDATE, DELETE) operation on a database table.
APPLICATION OF TRIGGERS
Triggers can be used for many things, including

Maintaining complex integrity constraints not possible through declarative


constraints enabled at table creation.
Auditing information in a table by recording the changes made and who made
them.
Automatically signaling other programs that action needs to takes place,
when changes are made to a table.

43/117

Oracle

pl/sql programming

CREATING TRIGGERS
SYNTAX
The general syntax for creating a trigger is:
CREATE [OR REPLACE] TRIGGER trigger _name
[BEFORE | AFTER ] triggering event ON table_reference [For EACH
ROW ]
[ WHEN trigger_condition ]
trigger_body;
where
trigger_name -the name of the trigger
triggering-event The event or time when the trigger fires.
Table_reference The table for which the trigger is defined
Trigger_body
Main code for the trigger
Trigger_condition The body of the trigger is executed only when the
condition evaluates to TRUE.
EXAMPLE
As an example, suppose we want to track statistics about different
category of subscribers, exchange wise. We want to
store these results in exg_stats table. The following script will create the
table exg_stats.
CREATE TABLE exg_stats
(exg_code CHAR (5),
cat_code NUMBER(2);
no_of_subs NUMBER (5));
In order to keep the table exg_stats up-to-date, We can create a trigger
on the table master_data that will update table exg_stats every time the
table master _data is modified. The update_ES TRIGGER shown next
does this. After any DML operation on the tableMaster_data the trigger
update_ES will execute. The body of the trigger queries the table
master_data and updates the table exg_stats with the current statistics.
CREATE OR REPLACE TRIGGER update_ES
/* Keeps the major_stats table up-to-date with the changes made to the
table master_data*/
AFTER INSERT OR DELETE OR UPDATE ON master_data

44/117

Oracle

pl/sql programming
DECLARE
CURSOR c_stats IS
SELECT exg_code,cat_code, count (*), no_of_subs
FROM master_data
GROUP BY exg_code,cat_code;
BEGIN
/*Loop through each record of the table exg_stats. Attempt to update the
statistics. If the row does not exit, create it */
FOR v_statsRecord IN C_stats LOOP
UPDATE exg_stats
SET no_of_subs = v_statsRecord.no_subs
WHERE exg_code = v_statsRecord.exg_code
AND Cat_code = v_statsRecord.cat_code;
/*Check to see if the row exists*/
IF SQL%NOTFOUND THEN
INSERT INTO exg_stats (exg_code,cat_code,no_of_subs)
VALUES (v_statsRecord.exg_code,v_stats
Record.cat_code,v_statsRecord.no_subs);
END IF;
END LOOP;
END update_ES;

TRIGGER COMPONENTS
1.Trigger name
2.Triggering event
3.The body
4.When clause -optional.
Trigger Name
Namespace: A namespace is the set of legal identifiers available for use as the
names of an object. Within one database shema ,all objects in the same
namespace must have unique name. Procedures, Packages and Tables all share
the same namespace. Hence it is illegal to give the same name to a procedure
and a table.
The namespace for triggers is different from that of the above objects (i.e.,
procedure, package and table). This means that a trigger can have same name
as a table or a procedure.

45/117

Oracle

pl/sql programming

Trigger names are database identifiers and as such follows the same rules as
other identifiers.
Although it is possible to use the same name for a trigger and a table. It is
better to give each trigger a unique name that identifies its function as well as the
table at which it is defined.
Triggering event
The triggering event determines the type of the triggers.
Triggers can be defined for INSERT, UPDATE or DELETE operation.
Triggers can be fired BEFORE or AFTER the operation.
They can also be fired ROW or STATEMENT level
TABLE I
Category
Statement
Timing
Level

Values
INSERT
DELETE
UPDATE
BEFORE
AFTER
ROW

Comments
Defines which kind of DML statement
causes the trigger to fire.
Defines whether the trigger fires before or
after the statement is executed.
Fires once for each row affected by the
triggering Statement.
Fires only once either before or after the
statement.

STATEMENT
TABLE 2
Timing

Statement

Level

BEFORE

INSERT
UPDATE
DELETE

ROW

AFTER

STATEMENT

The values for the timing, statement and level determine the type of the trigger.
From the table 2 it can be observed that there are total of possible 12 types.
2 timings x 3 statement x 2 levels = 12 types
For example all the following are valid trigger types.

46/117

Oracle

pl/sql programming

BEFORE UPDATE ROW level


AFTER INSERT STATEMENT level
BEFORE DELETE ROW level
AFTER UPDATE STATEMENT level.
A table can have upto 12 triggers defined on it-one of each type. A table can
have more than one trigger of each type.
This means that a table can have any number of triggers.
The order in which the triggers are fired is explained later in this chapter.
A trigger can also be fired for more than one type of triggering statement.
For example, the update_ES Trigger is fired on INSERT, UPDATE and
DELETE statements.
The body of the Trigger

The body of a trigger is a PL/SQL Block. Any statement that is legal in a


PL/SQL block is legal in a trigger body subject to the following restrictions.
A Trigger may not issue any transactional control statements (COMMIT,
ROLLBACK,SAVEPOINT). When the triggering statement is committed or
rolledback the work in the trigger is committed or rolled back as well.
Any procedures or functions that are called by the trigger body cannot
issue any transaction control statements.
The trigger body cannot declare any LONG or LONG RAW variables.
:new and :old (explained latter) cannot refer to a LONG or LONG RAW
column in the table for which the trigger is defined.

ORDER OF TRIGGER FIRING


Triggers are fired as the DMLstatement is executed. The algorithm or the
order at which different types of triggers are fired and the DML statement is
executed are given below.
1.Execute the BEFORE statement level trigger, if present.
2.For each row affected by the statement.
i.
Execute the BEFORE row-level trigger, if present.
ii.
Execute the statement itself.
iii.
Execute the AFTER row-level Trigger, if present.
3.Execute the AFTER statement-level Trigger, if present

47/117

Oracle

pl/sql programming

To illustrate, suppose we create all four kinds of update triggers on


the Staff table. Before after statement and Row level as follows.
Example
/* ******* To create otf_table******** */
CREATE TABLE otf_table
(ord_no NUMBER (5),
tgr_type CHAR(25));
/* ******* To create the sequence tgr_seq ******* */
CREATE SEQUENCE tgr-seq
START WITH 1
INCREMENT BY 1;
/* ***** before statement trigger ****** */
CREATE OR REPLACE TRIGGER staff_Bstatement
BEFORE UPDATE ON staff
BEGIN
Insert into otf_table (ord_no,tgr_type)
VALUES (tgr_seq.NEXTVAL,
before Statement trigger );
END staff_Bstatement;
/* ***** After Statement Trigger****** */
CREATE OR REPLACE TRIGGER Staff_Astatement
AFTER UPDATE ON staff
BEGIN
INSERT INTO otf_table (ord_no,tgr_type)
VALUES (tgr_seq.NEXTVAL, After Statement Trigger );
Staff_Astatement;
/* ***** Before Row Trigger ******* */
CREATE OR REPLACE TRIGGER STAFF_Brow
BEFORE UPDATE ON staff
FOR EACH ROW
BEGIN
INSERT INTO otf_ table (ord_no,tgr_type)
VALUES (tgr_seq.NEXTVAL , Before Row Trigger);
END staff _Brow;
/* ***** After Row Trigger ***** */
CREATE OR REPLACE TRIGGER staff_Arow
AFTER UPDATE ON staff
FOR EACH ROW
BEGIN

48/117

END

Oracle

pl/sql programming
INSERT INTO otf_table (ord_no,tgr_type)
VALUES (tgr_seq.NEXTVAL, After Row Trigger);
END staff_Arow;
/* To test the otf_trigger*/
UPDATE staff
SET Salary = 10000
WHERE desgn = AO;

As each trigger is fired, it will see the changes made by earlier


triggers as well as any data base changes made by earlier triggers as well as
any database changes made by the statement so far.
USING :OLD AND :NEW IN ROW LEVEL TRIGGERS
A row level trigger fire once per row processed by the triggering
statement. Inside the trigger, the row that is currently being processed can be
accessed, by using two pseudo records. :old and :new. Although syntactically
they are treated as records, in reality they are not records. Hence they can be
known as pseudo-records. The type of :old and :new is:
Triggering_table%ROWTYPE;
Where triggering_table is the table for which the trigger is defined.
The colon in front of new and old is required since they are
implemented as bind variables. The colon delimits them from regular PL/SQL
variables. A reference such as :new.field will be valid, only if field, is a field in
the triggering table.
Triggering
Statement
INSERT

:Old

:new

Undefined-All fields
Are NULL

UPDATE

Original values for the row


before the update.

DELETE

Original values before the


row is deleted

Values that will be inserted


when the statement is
complete.
New values that will be
updated when the statement
is complete.
Undefined All fields are
Null.

TABLE-3
The Table-3 shows the value of :new and :old with reference to each
statement. In reality, :new and :old are not records. As a result, operations that
would normally be valid on records are not valid for :new and :old . For example,

49/117

Oracle

pl/sql programming

i.
They cannot be assigned as entire record. Only the individual fields within
them may be assigned.
ii.
:old and :new cannot be passed to procedures or functions that take
arguments of triggering_table%ROW TYPE.
The Generate_EmpId trigger shown next uses :new. It is a BEFORE INSERT
OR UPDATE Trigger and its purpose is to fill in the ID field of staff with a value
generated from the emd_id__seq sequence.
Example:
The trigger Generate_EmpId actually modifies the value of
:new.emp_id. When the statement is actually executed, whatever values in :new
will be used. With Generate_EmpId, we can issue an INSERTstatement such as:
INSERT INTO STAFF (emp_name, desgn)
VALUES JOSE, AO);
Without generating an error. Even though we have not specified a value for
the primary key column emp_id (which is required), the trigger will supply it.
Infact, even if we do specify a value for emp_id, it will be ignored, since the
trigger changes it.
If we issue
INSERT INTO staff (emp_id,emp_name,desgn)
VALUES (51,JOSE, AO);
We get the same behaviour. In either case, emp_id_seq.NEXTVAL will be used
for emp_id column.
This shows that, you cannot change :new in an AFTER ROW LEVEL trigger,
since the statement had already been processed.
Note:

In general, :new is modified only in a before row level trigger and :Old is
never modified, only read from.
The :new and :old records are only valid inside a ROW LEVEL triggers.
You will get a compile error, if you try to reference inside a STATEMENT
LEVEL trigger.

THE WHEN CLAUSE


50/117

Oracle

pl/sql programming

- The WHEN clause is valid for row level triggers only. If present, the trigger
body will be executed only for those rows that meet the condition specified by the
WHEN clause. The WHEN clause looks like:
WHEN condition
- Where condition is a Boolean expression. It will be evaluated for each row.
The :new and :old records can be referenced inside conditions as well, but the
colon is not used there. The colon is only valid in the trigger body. For example,
the body of the check_salary trigger is only executed if the salary of an employee
is more than 10000.
CREATE OR REPLACE TRIGGER Check _salary
BEFORE INSERT OR UPDATE OF salary ON employee
FOR EACH ROW
WHEN ( :new.salary > 10000)
BEGIN
/* Trigger body goes here. */
END;
Check _Salary could also be written as follows:
CREATE OR REPLACE TRIGGER check_salary
BEFORE INSERT OR UPDATE OF salary ON students
FOR EACH ROW
BEGIN
IF :new.salary > 10000 THEN
/* Trigger body goes here */
END IF;
END;
USING TRIGGER PREDICATES:
INSERTING, UPDATING AND DELETING
The update_trigger earlier in this chapter is an INSERT, UPDATE and a
DELETE TRIGGE. Inside a trigger of this type (that will fire for different kinds of
DML statements), there are three Boolean functions that you can use to
determine what the operation is. These predicates are INSERTING, UPDATING
and DELETING. Their behaviour is described in the following table.
Predicate
INSERTING

Behavior
TRUE, if the triggering statement is an
INSERT;FALSE otherwise.
51/117

Oracle
UPDATING
DELETING

pl/sql programming
TRUE if the triggering statement is an
UPDATE;FALSE otherwise.
TRUE if the triggering statement is a
DELETE;FALSE otherwise.

The Log_Staff_changes trigger uses these predicates to record all


changes made to the staff table. In addition to the change, it records the user,
who makes the change. The records are kept in the staff_audit table, which look
like:
/* To create table staff_audit */
CREATE TABLE staff_audit
(old_emp_id NUMBER(2),
old_emp_name CHAR(20),
old_desgn NUMBER(5),
old_co_id CHAR(2),
old_salary NUMBER(6),
new_emp_id NUMBER(2),
new_emp_name CHAR(20),
new_desgn NUMBER(5),
new_co_id CHAR(2),
new_salary NUMBER(6),
change_type CHAR(1),
changed_by VARCHAR2(8),
Timestamp DATE);
/* To create Log _Staff _changes trigger */
CREATE OR REPLACE TRIGGER log_staff_changes
BEFORE INSERT OR DELETE OR UPDATE ON Staff
FOR EACH ROW
Declare
V_change TYPE CHAR(1);
BEGIN
/*Use I for an INSERT, D FOR delete, and U for UPDATE */
IF INSERTING THEN
v _change_type := I;
ELSIF
UPDATING then
V_change_type := U;
ELSE
52/117

Oracle

pl/sql programming

V_change_type := D;
END IF;
/* Record all the changes made to staff table in staff_audit table. Use SYSDATE
to generate the timestamp, and USER to return the user_ id of the current user. */

INSERT INTO staff_audit


VALUES (change_type,changed_by,timestamp,old_emp_id,
old_emp_name,Old_desgn,old_co_id, old_salary, new_emp_id,
new_emp_name,new_desgn, new_co_id, new_salary);
END Log_Staff_Changes;
Triggers are commonly used for auditing, as log_ Staff_ changes. Oracle
provides auditing as part of the database, but triggers allow for more flexible
auditing. Log_ Staff_changes could be modified, for example, to record changes
made by certain people only . It could also check to see, if users have
permission to make changes and raise an error (with
RAISE_APPLICATION_ERROR ) , if they dont have.

53/117

Oracle

pl/sql programming

Cursor

What is a Cursor ?
A cursor is a private SQL area
Every SQL statement executed by the oracle server has
an individual cursor associated with it.
Two Types of cursor:
-Implicit cursors: Declared for all DML and
PL/SQL SELECT statements.
-Explicit cursors: Declared and named by the
programmer.
The Oracle Serve uses work areas called Private SQL
areas to execute SQL statements and store processing
information. PL/SQL cursors let you name a private SQL area and
access its stored information. The cursor directs all phases of
processing.
Cursor Description
Type
Implicit Declared by PL/SQL implicitly for all DML
and PL/SQL SELECT statements.
Explicit Declared and named by the programmer
and manipulated through specific
statements within the blocks executable
actions.
Recall that the SELECT statement in PL/SQL must only return a
single row. PL/SQL actually attempts to fetch two rows from an
implicit cursor: one to satisfy the query and a second to see if
further rows were returned. One method to eliminate this extra fetch
is to use an explicit cursor.

Explicit Cursor Functions

Can process beyond the first row returned by the query, row by row.
Keep track of which row is currently being processed.
Allow the programmer to manually control them in the PL/SQL block.

54/117

Oracle

pl/sql programming

Controlling Explicit Cursors


Now that you have a conceptual understanding of cursors, review
the steps to use them. The syntax for each step follows :
Controlling Explicit Cursors Using Four Commands
1. Declare the cursor.
Declare the cursor by naming it and defining the structure of
the query to be performed within it.
2. Open the cursor.
The OPEN statement executes the query and binds any
variable that are referenced. Rows identified by the query are
called the ACTIVE SET and are now available for fetching.
3. Fetch data from the cursor.
The FETCH statement loads the current row from the cursor
into variables. Each fetch causes the cursor to move its pointer to
the next row in the active set. Therefore, each fetch will access a
different row returned by the query.
4.Close the cursor.
The CLOSE statement releases the active set of rows. It is
now possible to reopen the cursor to establish a fresh active set.
Controlling Explicit Cursors
no
DECLARE
EMPTY??
(1)

1.
2.
3.
4.
5.

FETC
H

OPEN

(2)

empty

(3)

(4)

CLOSE

yes
(5)

create a named SQLarea


Identify the active set
Load the current row into variables
Test for existing rows: return to FETCH if no rows found
Release the active set
Declaring the Cursor

55/117

Oracle

pl/sql programming

Use the CURSOR statement to declare an explicit cursor.


You can define parameter to allow substitution of values into the
query when the cursor is opened. You can also reference variables
within the query, but you must declare them before the cursor
statement.

Syntax:
DECLARE
CURSOR cursor_name IS
Select_statement;

Where:
Cursor_name

is a PL/SQL identifier.

Select_statement

is a SELECT statement without an INTO


clause.

Note: Do not include the INTO clause within the cursor declaration because it
appears later within the FETCH statement.

Opening the Cursor


Open the cursor to execute the query and identify the active set,
after specifying values for all input variables. The cursor will now point to
the first row in the active set.
Syntax
OPEN cursor_name;
Where:
Cursor_name

is the name of the previously-declared

56/117

cursor.

Oracle

pl/sql programming

Note: If the query returns no rows when the cursor is opened, PL/SQL does not
raise an exception. However, you can test the cursor_ status after a fetch.
Opening the Cursor : Syntax

Open the cursor to execute the query and identify the active set.
OPEN cursor_name;
If the query returns no rows, no exception is raised.
Test the outcome after a fetch by using cursor attributes.

Fetching Data from the Cursor


Use the FETCH statement to retrieve the current row values into
output variables. After the fetch, you can manipulate the variables by
further statements.
Syntax
FETCH cursor_name INTO variablel, variable2 .. . . . ;

Where:
cursor-name
Variable

is the name of the previously declared cursor.


is an output variable to store the results.

Guidelines:

Include the same number of variables within the INTO clause of the
FETCH statement as output columns in the SELECT statement and be
sure that the data types are compatible.
Match each variable to correspond to the columns positionally.
Alternatively, define a record for the cursor and reference the record in the
FETCH INTO clause.
Test to see if the cursor contain rows. If a fetch acquires no values, that is
there are now rows left to process in the active set and no error is
recorded.

57/117

Oracle

pl/sql programming
Fetching Data from the Cursor: Syntax:
Retrieving the current row values into output variables.
FETCH cursor_name INTO variable1,
variable2;
Include the same number of variables.
Match each variable to correspond to the columns
positionally.
Test to see if the cursor contains rows.

Fetching Data from the Cursor: Example


Retrieve the line items of an order, one-by-one
FETCH item_cursor
INTO v_product_id, v_item_total;

Closing the Cursor


Close the cursor after completing the processing of the SELECT
statement. This step allows the cursor to be reopened. Therefore, you
can establish an active set several times.
Syntax{
CLOSE cursor_name;
Where:
cursor-name

is the name of the previously declared

cursor.

Note: Do not attempt to fetch data from a cursor once it has been closed
or the INVALID_CURSOR exception will be raised.

58/117

Oracle

pl/sql programming
Closing the Cursor: Syntax

Close the cursor after completing the


processing of the rows.
CLOSE cursor_name;
Reopen the cursor, again, if required
Do not attempt to fetch data from a cursor
,once it has been closed.

Explicit Cursor Attributes


As with implicit cursors, there are four attributes for obtaining status
information about a cursor. When used, the attribute name is preceded
by the cursor identifier.
Cursor Attribute

Description

%ISOPEN

Boolean attribute that evaluates to TRUE if the cursor


is open.

%Notfound

Boolean attribute that evaluates to TRUE if the most


recent fetch does not return a row.

%FOUND

Boolean attribute that evaluates to TRUE until the most


recent fetch does not return a row, complement of
%NOTFOUND.

%ROWCOUNT

Numeric attribute that evaluates to the total number of


rows returned so far.

Note: Do not reference cursor attributes directly within a SQL statement

59/117

Oracle

pl/sql programming

Controlling Multiple Fetches from Explicit Cursors


Typically, when you want to process several rows from an explicit
cursor, you define a loop to perform a fetch on each literation. Eventually,
all rows in the active set will be processed, and an unsuccessful fetch sets
the %NOTFOUND attribute to TRUE . Use the explicit cursor attributes to
test success of each fetch before any further references are made to the
cursor. If you omit an exist criteria, an infinite loop will result.
Controlling Multiple Fetches
Process several rows from an explicit cursor using a loop.
Fetch a row with each iteration.
Write a test for an unsuccessful fetch by using the %NOTFOUND
attribute.
Test success of each fetch using explicit cursor attributes.

You can only fetch rows when the cursor is open. Determine
whether the cursor is open using the %ISOPEN cursor attribute, if
necessary.
Fetch rows in a loop. Determine when to exit the loop by using
cursor attributes.
To retrieve an exact number of rows, fetch the rows in a numeric
FOR loop, or fetch the rows in a simple loop and determine when
to exist the loop by using the %ROWCOUNT cursor attribute.
Example:
Retrieve the first five line items for an order one by one. Print the
cumulative total for each product to the screen.
PROCEDURE ord_process
V_ord_id IN s_item.ord_id%TYPE;
IS
V_product_id s_item.product_id%TYPE;
V_item_total NUMBER (11,2);
V_order_total NUMBER (11,2) :=0;
CURSOR item_cursor IS
SELECT product_id, price * quantity
FROM
s_item
60/117

Oracle

pl/sql programming
WHERE ord_id = v_ord_id;
BEGIN
OPEN item_cursor;
LOOP
FETCH item_cursor INTO v_product_id ,
V_item_total;
EXIT WHEN item_cursor%ROWCOUNT > 5
OR item_cursor%NOTFOUND;
V_order_total := v_order_total + v_item_total;
TEXT_IO.PUT_LINE ( Product ID ||
TO_CHAR (v_product_id) ||
has a total of ||
TO CHAR(v_order_total , $999,999,999.99));
END LOOP;
CLOSE item_cursor;
COMMIT;
END ord_process;

Note: If using %ROWCOUNT, add a test for no rows in the cursor by using
the %NOTFOUND attribute because the row count is not incremented if
the fetch does not retrieve any rows.
The %ISOPEN Attribute: Example
Fetch rows only when the cursor is open.
Test if the cursor is open using %ISOPEN cursor attribute before
performing a fetch.
IF item_cursor %ISOPEN THEN
FETCH item-cursor INTO v_quantity, v_price,
ELSE
OPEN item-cursor;
END IF;

61/117

Oracle

pl/sql programming
The %NOTFOUND and
%ROWCOUNT Attributes; Example
Retrieve an exact number of rows using the %ROWCOUNT cursor attribute.
Determine when to exist the loop using the %NOTFOUND cursor attribute.

LOOP
FETCH item_cursor
INTO v_product_id, v_item_total;
EXIT WHEN item_cursor%ROWCOUNT > 5
OR item_cursor%NOTFOUND;
V_order_total := v_order_total + v_item_total;
.
END LOOP;

Cursors and Records


We have already seen that you can define records to use the
structure of columns in a table. You can also define a record based on the
selected list of columns in an explicit cursor. This is convenient for
processing the rows of the active set since you can simply fetch into the
record. Therefore, the values of the row are loaded directly into the
corresponding fields of the record.
In the example, you can select the ROWID pseudo_column, and it
will have a corresponding field within the EMP_RECORD PL/SQL record.

62/117

Oracle

pl/sql programming

Cursors and Records: Example


Process the rows of the active set conveniently
by fetching values into the PL/SQL RECORD.
Cursor EMP_CURSOR is
SELECT id, salary, start_date, rowid
FROM s_emp
WHERE dept_id = 41 ;
Emp_record emp_cursor%ROWTYPE;
BEGIN
OPEN emp_cursor;
...
FETCH emp_cursor INTO emp_record;

Cursor FOR Loops


A cursor FOR loop processes rows in an explicit cursor. It is a shortcut in
because the cursor is opened, rows are fetched once for each iteration in the
loop, and the cursor is closed automatically when all rows have been
processed. The loop itself is terminated automatically at the end of the iteration
where the last row was fetched.
Syntax
FOR record_name IN cursor_name LOOP
Statement1;
Statement2;
..
END LOOP;
Where;
record-name is the name of the implicitly-declared record.
Cursor-name is a PL/SQL identifier for the previously-declared cursor.
Guidelines

Do not declare the record that controls the loop. Its scope is only in the
loop.
Test the cursor attributes during the loop, if required.

63/117

Oracle

pl/sql programming
Supply the parameters for a cursor, if required, in parentheses following
the cursor name in the FOR statement.
Do not use a cursor FOR loop when the cursor operations have to be
handled manually.

Shortcut to process explicit cursors.


Implicit open, fetch, and close occur.

FOR record_name IN cursor_name


LOOP
Statement1;
Statement2;
...
END LOOP;

Do not declare the record; it is implicitly declared.

Cursor FOR Loops: Example


Retrieve line items for an order one by one ,until there are no
more line items left.
FOR item_record IN item_cursor LOOP
- -Implicit open and implicit fetch - occur
v_order_total : =v_order_total +
( item_record.price *
item_record.quantity);
i := i + 1;
product_id_table ( l ) :=
item_record.product_id;
order_total_table ( i ) :=v-order-total;
END LOOP;
- -implicit close occurs.

64/117

Oracle

pl/sql programming

Summary
Cursor Types

Implicit cursors are used for all DML statements and single row queries.
Explicit cursors are used for queries of zero, one, or more rows.

Explicit Cursor Commands

Declare the cursor.


Open the cursor.
Fetch data from the cursor.
Close the cursor.

Cursor Attributes
Evaluates the status of the cursor by using cursor attributes.
Cursors with Parameters
Use parameter to open an explicit cursor several times in a block, returning a
different active set on each occasion.
Cursor FOR Loops

65/117

Oracle

pl/sql programming

Use cursor FOR loops as a shortcut to open the cursor, fetch rows once for each
loops iteration, and automatically close the cursor after all rows are processed.

CHAPTER 3
STORED PROCEDURES, FUNCTIONS & PACKAGES
SUBPROGRAM
Program units are named PL/SQL blocks. They fall into three main
categories.

Procedures to perform actions


Functions to compute a value
Packages to bundle logically related procedures and functions

Stored or Application Subprogram ?


These program units can be created in a variety of environments,
including server-side stored subprograms or as application subprograms.

Concept
Location
Executed

Stored Subprogram
Is in the database
From any database tool
or application

66/117

Application Subprogram
Is within the application.
From only the application
in which it was created.

Oracle

pl/sql programming

Availability

By way of database
security.

Independently of, and in


addition to, stored
subprograms.

Subprograms are composed of a number of sections.

A header to name and type the block


An optional declarative section to set up local identifiers
An executable part to perform the actions
An optional exception handling section to handle exceptions.

What Are PL/SQL Program Units ?


Named PL/SQL blocks
Three main categories:
- Procedures to perform actions
- Functions to compute a value
- packages to bundle logically related procedures and functions.
Stored in the database or developed as an application
subprogram.

67/117

Oracle

pl/sql programming
Subprogram Components
HEADER -Mandatory
- -subprogram name,type,and
arguments
DECLARATIVE -Optional
- -Local identifiers
EXECUTABLE -Mandatory
- -SQL Statements
- -PL/SQL control statements
EXCEPTION HANDLING-Optional
- -Actions to perform when errors
occur
END; - Mandatory

Creating a Subprogram

Select environment

Invoke

68/117

Oracle

pl/sql programming

The following steps will assist you to create a subprogram.


1.

Select your environment.

If using Procedure Builder, then select either the Program Units


node or the Database Objects node and Stored Procedures Units
subobject node.
2.

Write your syntax.

If using Procedure Builder, enter the syntax in the Program Unit


Editor. If using SQL*Plus, write your code in a text editor as a script file.
3.

Compile your code.

The source code is compiled into p-code. If using Procedure


Builder, click the Compile button. If using SQL*Plus, start your file at the
SQL prompt.
4.

Invoke the successfully compiled procedure or function.

Guidelines

SQL*Plus is another development environment for writing and for


initial testing of a procedure, although you will need to test the
procedure by invoking it from an application.
The SQL commands issued to create a stored subprogram are
CREATE PROCEDURE or CREATE FUNCTION.
The SQL commands issued to remove a stored subprogram are
DROP PROCEDURE or DROP FUNCTION.
Use CREATE OR REPLACE PROCEDURE or CREATE OR
REPLACE FUNCTION ,so you do not have to issue a DROP
statement.

STORED PROCEDURES
Create a PL/SQL procedure to store a series of actions for later
execution. The procedure can contain zero or more parameters, which
are arguments that you list when calling the procedure.

69/117

Oracle

pl/sql programming

Creating a Procedure Syntax:


PROCEDURE name
[ (parameter1, para2, ) ]
IS
Pl/sql-block;

Where:
Name
Parameter

is the procedure name, which adheres to the standard


Oracle naming rules.
is the parameter syntax shown below.

PL/SQL_BLOCK

- is the procedural body that defines the action


by the procedure.

performed

The parameter syntax is as follows:

Syntax
Parameter_name [ IN | OUT | IN OUT ] datatype
[ { := | DEFAULT } expr ]

Where:
Parameter_name - is the name of the parameter.
Datatype
- is the data type of the parameter, without constraints.
Expr
- is the value to initialize the parameter.
Guidelines

Start the PL/SQL block with the keyword IS .


Enter any local declaration between IS and BEGIN

70/117

Oracle

pl/sql programming

Do not specify a constraint on the data type.


When creating the procedure from procedure Builder, the
CREATE OR REPLACE portion of the syntax is implied.
Therefore, when creating the procedure from SQL*Plus , begin
the statement with CREATE OR REPLACE.

Creating a Procedure: Guidelines

Use the CREATE OR REPLACE clause when building


your procedure in SQL*Plus
Enter any parameters.
Start the PL/SQL BLOCK WITH IS
Enter a local variable declaration or the keyword BEGIN
after IS.

Procedural Parameters
Transfer values to and from the calling environment through parameters.
There are two types that you use. When declaring a procedure, the formal
parameter is used to define the values used in the executable portion of the
PL/SQL block. The actual parameter, or argument, is referenced when
invoking a subprogram.

Parameter Modes for Formal Parameters


Parameter
Mode
IN

OUT

Description
Default argument.
Passes a value from the calling environment into the
subprogram.
Formal parameter acts as a constant -you cannot overwrite the
value.
Actual parameter can be an expression, a constant, a literal, or
an initialized variable.
Must be specified.
Returns a value from the procedure to the calling environment.
Formal parameter acts as an uninitialized variable.
Formal parameter cannot be assigned to another variable or to
itself.

71/117

Oracle

IN OUT

pl/sql programming
Actual parameter must be a variable ; it cannot be a constant
or expression.
Must be specified.
Passes a value from the calling environment into the
procedure, and returns a possibly different value from the
procedure to the calling environment.
Formal parameter acts as an initialized variable.
Formal parameter can be used as a normal variable, it can be
assigned to a value.
Actual parameter must be a variable.

Creating a Procedure :Example


PROCEDURE change_salary
(v_emp_id IN NUMBER,
v_new_salary IN NUMBER)
IS
BEGIN
UPDATE s_emp
SET Salary = v_newsalary
WHERE id = v_emp_id;
COMMIT;
END change_salary;

72/117

Oracle

pl/sql programming

Parameter Modes for Formal Parameters


IN
Default
Value is passed into sub
Program.

OUT
Must be specified
Returned to calling
environment

Formal parameter act as


a constant.
Actual parameter can be
a literal,
expression,constant or
Initialized variable.

An initialized variable.

IN OUT
Must be specified.
Passed into subprogram:
Returned to calling
environment.
An initialized variable.

Must be a variable.

Must be a variable.

Example:
Update the salary of the specified employee to the specified amount through a
procedure.
PROCEDURE change_salary
(v_emp_id IN NUMBER,
v_new_salary IN NUMBER)
- - formal parameters
IS
BEGIN - begin PL/SQL block
UPDATE s_emp
SET
salary = v_new_salary
WHERE id = v_emp_id;
COMMIT;
END change_salary;

This procedure, when invoked, will take the parameters for the employee
number and the new salary, and update the salary for that specified employee.
Eliminate Unnecessary IN Arguments

73/117

Oracle

pl/sql programming
Where possible, derive values in the procedure, or use column default
values.
Generate the primary key using a database sequence.
Record the username from the USER function.
Record the current date from the SYDATE FUNCTION.
Take advantage of business rules to compute input values automatically
using a formula.
FUNCTION

Create a PL/SQL function to return a value to the calling environment.


You must declare the RETURN data type in the header section of the function
definition, and define the value to be returned in the PL/SQL block. You can also
declare a list of parameters to be passed into the function.
Create function Syntax:
FUNCTION name
[ (Parameter1, para2, ...) ]
RETURN datatype
IS
Pl/sql_block;
Where:
Name

is the function name, which adheres to the standard Oracle


naming rules.

Parameter
Data type

is the parameter syntax similar to procedure


is the data type of the value to be returned.

Pl/sql_block

is the procedural body that defines the action


Performed by the procedure.

The RETURN statement


Remember to include a RETURN statement in the PL/SQL block. The
function must set the value of the return parameter and be of the same data type
specified in the RETURN clause of the function definition. Multiple RETURN
statements are allowed, but only one will be executed by any one call. Typically,
the multiple RETURN statements are within an IF statement.
When creating the function from Procedure Builder, the CREATE
OR REPLACE portion of the syntax is implied. Therefore, when
creating the function from SQL*Plus, Begin the statement with
CREATE OR REPLACE.

74/117

Oracle

pl/sql programming

Creating a Function

Create a PL/SQL function to return a value to the calling


environment.
Add a RETURN clause with the data type in the declaration of
the function.
Include at least one return statement in the PL/SQL block.

Creating a Function: Syntax


FUNCTION name
[ (parameter1, par2, ..) ]
RETURN data type
IS
Pl/sql-block;

Example:
Return the tax based on the value parameter in a function
FUNCTION tax
(v_value IN NUMBER)
RETURN NUMBER
IS
BEGIN
RETURN (v_value * .07);
END tax;
Avoid using the OUT and IN OUT modes with FUNCTIONS.
Functions are designed to return a single value.

75/117

Oracle

pl/sql programming
PACKAGES

INTRODUCTION
Packages are PL/SQL objects that group other object such as
procedures, functions, types, variables, SQL Cursors and Exceptions as a single
unit with less restriction with respect to dependencies. This is another ADA
feature incorporated in PL/SQL . Packages also provide global variables for
PL/SQL. So packages allow multiple procedures to use the same Variables and
cursors. Procedures within packages may be available to the public in which
case they are accessible to the users of the package or they may be private, in
which case they are only accessible via commands from within the package such
as call from other procedures.
Each package has two parts: The specification and the body. Each of
them stored separately in the data dictionary. The package specification is also
known as the package header. It contains information about the objects you can
access when you use the package. However it does not contain the code for any
procedure.
CREATING PACKAGE
When creating package, the package Specification and the package body
are created separately. Thus there are two commands to use (1) CREATE
PACKAGE for package Specification, and (2)CREATE PACKAGE BODY for the
package body. Both of these commands require that you have the CREATE
PROCEDURE System Privilege. If the package is to be created in a schema
other than your own, then you must have the CREATE ANY PROCEDURE
System privilege.
The Syntax for creating package specification is:
CREATE [ or REPLACE ] package [user.] package_name
{ IS/AS }
procedure_specification |
function_specification |
variable_declaration |
exception_declaration |
cursor_declaration
type_definition
END [package_name];
Where package-name is the name of the package

76/117

Oracle

pl/sql programming

A Package specification consists of the elements of the program such as


functions, procedures, variables, constants, cursors and exceptions which are
the same as they would be in the declarative section of an anonymous block.
The same rules apply for a package header as for a declarative section, except
for procedure & function declarations
The rules are as follows:
Package elements can appear in any order. However as in a declarative
section, an object must be declared before it is being referenced; if a
cursor contains a variable as part of the where clause, it must be declared
before cursor declaration.
All types of elements do not have to be present. A package contains only
procedure & function specification, for example, without declaring any
exceptions or types.
Any declarations for procedures or functions must be forward declaration.
This is different from the declarative section of a block, where both forward
declaration and actual code for procedures or functions may be found.
The code which implements the packages procedures or functions is
found in the package body.

Example:
CREATE PACKAGE salary_package
As
PROCEDURE addemp (p_staffno IN emp_data.staffno%TYPE,
P_emp_name IN emp_data. Emp_name%TYPE,
P_desgn IN emp_data.desgn%TYPE, p_dob IN
Emp_data.dob%TYPE, p_hq IN emp_data.Hq%TYPE,
p_deptno IN Emp_data.deptno%TYPE);
PROCEDURE salupd (p_staffno IN emp_sal.staffno%TYPE,
P_basic IN Emp_sal.basic%TYPE,p_gpf_sub IN
emp_sal.gpf_sub%TYPE,p_gpf_rec
IN emp_sal.gpf_rec%TYPE,p_qtrs IN
emp_sal.qtrs%TYPE);
PROCEDURE Paybillgen;
PROCEDURE Paycalc (p_staffno IN emp_data.staffno%TYPE);
FUNCTION DA (p_basic IN emp_sal.basic%type)
RETURN number;
FUNCTION hra (p_basic IN emp_sal.basic%TYPE,
p_qtrs IN emp_sal.qtrs%TYPE)
77/117

Oracle

pl/sql programming
RETURN number;

END salar_package;
THE PACKAGE BODY
The package body fully defines the code for all the objects listed in the
specification and can contain additional objects not listed in package
specification. The second one objects is said to be private and are not available
to the users of the package. Private objects may only be called by other objects
within the same package body. The syntax for creating package body is:
CREATE [or REPLACE] PACKAGE BODY [User.]package_body
[IS/ AS]
PL/SQL package body;
Where package-body is the name of the package body which should be
the same as the name of the package specification. Continuing the
SALARY_PACKAGE example, its package body can be created via the
CREATE PACKAGE BODY command as follows;
Example:
CREATE PACKAGE BODY salary_package
AS
Crtdate DATE;
Crtmonth varchar2(9);
PROCEDURE addemp (p_staffno IN
emp_data.staffno%TYPE, p_emp_name IN
emp_data.emp_name%TYPE, p_desgn IN
emp_data.desgn%TYPE,
p_dob IN emp_data.dob%TYPE, p_hq IN
emp_data.hq%TYPE,
p_deptno IN emp_data.deptno%TYPE)
IS
V_deptno emp_data.deptno%TYPE;
Empty_staffno EXCEPTION;
BEGIN
IF p_staffno IS NULL
RAISE empty_staffno;
ELSE
SELECT deptno into v_deptno
78/117

Oracle

pl/sql programming

FROM dept
WHERE deptno = p_deptno;
INSERT INTO emp_data
VALUES(p_staffno, p_emp_name, p_desgn, p_dob,
p_hq, p_deptno);
INSERT INTO new_emp
VALUES (p_staffno,p_emp_name,crtdate,crtmonth);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND then
RAISE_APPLICATION_ERROR( -20001,
Department No: || p_deptno || does not exist );
WHEN DUP_VAL_ON_INDEX then
RAISE_APPLICATION_ERROR( -20002,
Staff Number : || p_staffno || should not be empty );
END addemp;
PROCEDURE salupd (p_staffno IN emp_sal.staffno%TYPE,
P_basic IN emp_sal.basic%TYPE,
P_gpf_sub IN emp_sal.gpf_sub%TYPE,
P_gpf_rec IN emp_sal.gpf_rec%TYPE,
P_qtrs emp_sal.qtrs%TYPE)
IS
Begin
Update emp_sal
SET basic = p_basic,
Gpf-sub
= p_gpf_sub,
Gpf-rec
= p_gpf_rec,
Qtrs
= p_qtrs
WHERE staffno = p_staffno;
COMMIT;
END salupd;
PROCEDURE paycalc (p_staffno IN emp_data.staffno%TYPE)
IS
Zero_pay EXCEPTION;
V_da number (6);
v-hra NUMBER (6);
v_cca number (6);
v_totpay
NUMBER (6);
v_netpay
number (6);
v_basic
emp_sal.basic%TYPE;
v_gpf_sub emp_sal.gpf_sub%TYPE;
v_gpf_rec emp_sal.gpf_rec%TYPE;

79/117

Oracle

pl/sql programming
v_qtrs
v_name
v_desgn

emp_sal.qtrs%TYPE;
emp_data.emp_name%TYPE;
emp_data.desgn%TYPE;

BEGIN
IF v_basic = 0 THEN
RAISE zero_pay;
END IF;
SELECT emp_nam, e_desgn INTO v_name,v_desgn
FROM emp-data
WHERE staffno = p_staffno;
SELECT basic,gpf_sub,gpf_rec,qtrs
INTO v_basic, v_gpf_sub,v_gpf_rec,v_qtrs
FROM emp_sal
WHERE staffno = p_staffno;
SELECT cca INTO v_cca
FROM allowrate;
V_da := da(v_basic);
V_hra := hra(v_basic,v_qtrs);
V_totpay := v_basic + v_da + v_hra + v_cca;
V_netpay := v_totpay v_gpf_sub v_gpf_rec;
INSERT INTO paybill
VALUES (p_staffno,v_name,v_desgn,v_basic,
v_da,v_hra,v_cca,v_totpay,v_netpay);
EXCEPTION
WHEN TOO_MANY_ROWS THEN
RAISE_APPLICATION_ERROR( -20001,
There are more than I records for this staffnumber: || p_staffno );
WHEN zero_pay THEN
RAISE_APPLICATION_ERROR( -20002,
Basic pay zero seems incorrect; It needs updatation);
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR( -20003,
There is no record of information for this staff no: || p_staffno);
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20004,
SOME OTHER ERROR HAS OCCURRED );
End paycalc;
PROCEDURE paybillgen

80/117

Oracle

pl/sql programming
IS
CURSOR payinfncur IS
SELECT staffno
FROM emp_data;
BEGIN
FOR pay_cur in payinfncur
LOOP
Paycalc(Pay_cur);
END LOOP;
END paybillgen;
FUNCTION da (p_basic IN emp_sal.basic%TYPE)
RETURN NUMBER
IS
V_da NUMBER (5);
V_darate NUMBER (5);
BEGIN
SELECT darate into v_darate
FROM allowrate;
V_da := p_basic*v_darate/100;
RETURN(v_da);
FUNCTION hra (p_basic IN emp_sal.basic%TYPE,
P_qtrs IN emp_sal.qtrs%TYPE)
RETURN NUMBER
IS
V_hra NUMBER(5);
V_hrarate
NUMBER (2);
BEGIN
SELECT hrarate into v_hrarate
FROM allowrate;
IF UPPER(p_qtrts) = Y THEN
V_hra := 0;
ELSE
V_hra := p_basic*v_hrarate/100;
END IF;
RETURN(v_hra);
End hra;
END salaray_package;

The create package body command shown in the above example


combines the code for the forward declarations of the da & hra functions with the
code for the forward declarations of the addemp, salupd, paycalc & paybillgen

81/117

Oracle

pl/sql programming

procedures in the package header. The END clauses all have the names of their
associated objects appended to them. Modifying the end clauses in this manner
helps to clarify the ending points of the object code. Objects that are not having
forward declarations, such as EXCEPTIONS ,can be referenced in the package
body without being referenced.
Additional functions, procedures, exceptions, variables, cursors and
constants may be defined within the package body, but they will not be available
to the public unless they have been declared within the package Specification
(via the CREATE PACKAGE command).
The package body is optional. If the package header does not contain any
procedure or function (only variable declarations, cursors, types and so on ), then
the body does not have to be present. This technique is used for declaring
global variables, since all objects in a package header are visible outside the
package.
Any forward declaration in the package header must be fleshed out in the
package body. The specification for the procedure or function must be the same
in both. This includes the name of the subprogram, its parameters and the mode
of the parameters.
PACKAGES SCOPE AND EXECUTION
Any object declared in a package header is in scope and is visible outside
the package by qualifying the object with the package name. Therefore, to
execute a procedure within a package, you must first list the package name, then
the procedure name.
Example;
EXECUTE salary_package.paycalc(1001);
However inside the package body, the object in the header can be referenced
without the package name.
PACKAGE INITIALIZATION
A package body may also include code that is run every time the package is
invoked, regardless of the part of the package that is executed. In the following
e.g., SALARY_PACKAGE package body is modified to include a SQL statement
that records the current date and the current month , at the start of the package
execution. Two new variables crtdate & crtmonth also have been declared in the
package body in order to record these values. Since the 2 new variables are
declared within the package body, they are not available to the public. Within the

82/117

Oracle

pl/sql programming

package body, they are separated from the procedures and functions. The
package initialization code is shown as follows:
CREATE OR REPLACE PACKAGE BODY salary_package
AS
Crtdate
DATE;
Crtmonth
varchar2(9);
.
BEGIN
SELECT sysdate, to_char(sydate, Month)
INTO crtdate, crtmonth
FROM dual;
END salary_package;
Note: The code that is to be run every time the package is executed is
stored in its own PL/SQL block at the bottom of the package body. It
does not have its own end clause; it uses the package bodys end
clause.
Every time the salary-package package is executed the crt date and crt
month variables will be populated by the query shown in the previous
listing. These 2 variables can then be used by the function &
procedures within the package ie; Addemp procedure uses this
variables for populating in the new_emp table.
DROPPING PACKAGES
Packages and its body can be dropped separately as follows:
To drop a package, use the drop package command as shown in the
following listings:
DROP PACKAGE Salary_package;
To drop a package body, use the drop package command with the body
clause, as shown in the following listings:
DROP PACKAGE BODY salary_package;
PACKAGES AND DEPENDENCIES
The Dependency picture for salary-package is shown below:

SALARY_PACKAGE DEPENDENCIES
83/117

Oracle

pl/sql programming

SALARY_PACKAGE
HEADER

SALARY_PACKAGE
BODY

The BODY of the


salary_package depends
on the header, but the
Header does not depend
On the body

The BODY of
salary_package
depends on the
emp_data, emp_sal
& Dept tables
EMP_DATA, EMP_SAL,
& DEPT

The package body depends on emp_data, emp_sl & dept tables and
package header. The package header does not depend on anything. This is the
advantage of packages. We can change the package body without having to
change the header. Therefore other objects which depend on the header wont
have to be recompiled at all , since they never get invalidated. If the header is
changed, this automatically invalidates the body, since the body depends on the
header.
We can examine the behaviour as follows:
In the previous salary_package package, we can refer it with the body and
the table emp_data.
We can query the information about the above objects as follows.
SELECT object_name, object_type,status
FROM user_objects
WHERE object_name IN (salary_package, emp_data);
OUTPUT:
OBJECT_NAME
SALARY_PACKAGE
SALARY_PACKAGE
EMP_DATA

OBJECT_TYPE
PACKAGE
PACKAGE BODY
TABLE

84/117

STATUS
VALID
VALID
VALID

Oracle

pl/sql programming

- Now change the package body only, by changing the following


statements. Note that the header is unchanged.
V_da := p_basic *v_darate / 100 + 100;
- When you compile by giving / , package body will be created.
- Now user_objects shows that package header is still valid.
SELECT object_name, object_type, status
FROM user_objects
WHERE object_name IN (salary_package, emp-data);
OUTPUT:
OBJECT_NAME
SALARY_PACKAGE
SALARY_PACKAGE
EMP_DATA

OBJECT_TYPE
PACKAGE
PACKAGE BODY
TABLE

STATUS
VALID
VALID
VALID

Even if we drop the table EMP_DATA, it only invalidates the package


body.
DROP TABLE emp_data;
Now you check the dependencies as follows.
SELECT object_name,object_type, status
FROM user_objects
WHERE object_name IN (salary_package, emp_data);
OUTPUT:
OBJECT_NAME
SALARY_PACKAGE
SALARY_PACKAGE

OBJECT_TYPE
PACKAGE
PACKAGE BODY

STATUS
VALID
INVALID

Only the package body becomes invalid.

85/117

Oracle

pl/sql programming
CHAPTER 4
ORACLE ARCHITECTURE AND USER MANAGEMENT
ARCHITECTURE OF THE ORACLE SERVER

The server product is simply an executable that performs important


activities when it is run. Access to the Oracle9i Database is supported by the
Oracle executable and a series of support routines and files that fall into the
categories described in the following list.

INIT.ora.
This file contains entries that determine the runtime
environment of the Oracle 9i database as it operates. The values for the
entries in this file control items such as the amount of memory allocated
to the instance and the breakdown of the structures within that memory.

Shared memory
Often referred to as RAM on the PC, this is an
amount of a computers memory that is acquired when an Oracle 9 i
database is started. This chunk of memory is acquired when the Oracle 9i
server is started and is affectionately called the SGA, or system global
area.

Database files
These fall into three categories-data files, control
files, and redo log files. The files that end in .dbf are data files, the ones in
.ctrl are control files, and .log files are online redo logs.

Support processes These are workers that are spawned when an


Oracle 9i instance is started, and they help to facilitate access to a set of
Oracle database files

Network access
This is enabled by Oracle 9is Oracle Net product,
Its precursors were SQL*Net, delivered with versions upto and including
Oracle7, and Net8 with all releases of Oracle8.

Trace files
These are continually written to as Oracle9i operates and
are deposited in locations specified in an instances INIT.ora. They
contain primiarily two kinds of descriptive information -certain types of
Oracle errors and timestamp information related to some significant
instance activities.

Runtime libraries
These are the equivalent of PC dynamic link libraries,
containing routines and service components that allow the Oracle9i server
to operate and perform a suite of sophisticated functionally on its user
communitys behalf.

86/117

Oracle

pl/sql programming

Let us have a brief look at what goes on as the Oracle9i server


operates.
Background Support Processes
Several background processes support the operation of an Oracle
9i instance and accept connection requests from users.
Database Writer (dbw0)
The database writer is responsible for writing contents of database
buffers to disk. Oracle marks buffers in memory as dirty when the data they
contain is changed. There is one database writer process by default, but you can
instruct Oracle 9i. to spawn up to an additional nine. When a user process needs
to access data that is not in the buffer cache, dbwr ensures that these sessions
can have access to free buffers to go about their work.
This is the only process that writes data to the database -think of it
as the keeper of all the write activities, taking minutes as the database operates.
Process Monitor (pmon)
The process monitor is responsible for carrying out cleanup if and
when any user sessions are ended abnormally and they do not do it themselves.
An all-too-common activity is, when users abruptly end sessions against the
database by pressing CTRL-ALT-DELETE and rebooting their desktop
computers. Resources that may have been tied up by aborted sessions are
cleaned up and released by pmon. Let us call pmon the Secret Agent, slinking
around the database,assuming identifies of aborted user sessions, and
performing cleanup on their behalf.
System Monitor (smon)
The system monitor has a number of responsibilities, the primary
one only happening when the Oracle 9i instance is started. At startup, smons
job is to ensure that all the database files are consistent and perform recovery, if
required. There is also an assortment of other cleanup activities that may need
to be done, which are smons responsibility. Other background processes can
wake up smon if work needs doing . The smon process, by itself checks, every
so often, to see whether there are any tasks waiting for its attention. The work
performed by smon is integral to the smooth operation of any Oracle9i instance.
Let us call this process the Comptroller, ensuring that everything is being done
according to the book on an ongoing basis.

87/117

Oracle

pl/sql programming

Log Writer (lgwr)


The log writer is responsible for redo log buffer management.
The redo logs are Oracle9is transaction logs. Almost all activity against the
database is tracked in the online redo logs. As transactions are initiated, and
eventually committed (saved) or rolled back (abandoned), a record of this activity
is written to these log files. The log writer can write records of multiple
transactions to the redo log files, thereby maximizing its throughput and
performance. Writing this transaction information in batches rather than serially,
one at a time, is less time consuming and uses less resources. The log writer is
recording all the transactions against the virtual oracle 9i Database .
Checkpoint (ckpt)
When a check point activity begins, this process updates all the
database data files, with the details of the checkpoint. The database writer is the
only process that writes data to these database files, whereas the ckpt process
ensures the data files are in synch with one another after a checkpoint
completes. This process we call the Dispatcher -ensuring all is in synch.
Recoverer (reco)
The recoverer processs primary responsibility is to resolve failed
transactions in a distributed Oracle9i environment. This process automatically
connects to remote nodes, involved in a distributed transaction and resolves the
failed transactions, removing rows where appropriate from all nodes involved in
the failure. This recoverer process may attempt to connect to remote nodes more
than once for transaction resolution, with the delay time between consecutive
connections increasing each time.
Archiver (arc0)
The archiver process automatically saves copies of redo logs in a
DBA-specified storage location, when media recovery is enabled. We discuss
the circular usage of the online redo logs and the special form of media recovery
called archivelog mode in the upcoming section Redo Logs.. This is an
optional process spawned by log_archive_start = true in the INIT.ora.
A network of background processes supports the operation of an Oracle9i
database. We feel it is relevant to the understanding of the Oracle software, and
the management of the 9i database in particular, to cover details on how the
support processes do just that -support. Let us move on to the INIT.ora, the first
piece in the Oracle9i server O/S file layer.

88/117

Oracle

pl/sql programming

INIT.ora
The INIT.ora file is read when an Oracle9i instance is started .
Let us look at the type of parameters found in the INIT.ora file and a few
examples of each.
Location Entries
The first category of parameters describes the location of one or
more files required by or written to as the instance operates. In some cases, it
contains the fully pathed location, directory, and file name, as in control_files. In
other cases, it simply contains a directory name, as in db_create_file_dest.
When the instance is started, Oracle9i verifies that the directories and files
mentioned in INIT.ora exist and can be written to and read from. If there are any
problems, Oracle9i displays one or more error messages along the lines of those
shown in the next listing.
SQL> startup
ORA-00444: background process LGWR failed while starting
SQL>
SQL> startup
ORACLE instance started.
Total System Global Area 537691548 bytes
Fixed Size
279964 bytes
Variable Size
469762048 bytes
Database Buffers
67108864 bytes
Redo Buffers
540672 bytes
ORA-00205: error in identifying controlfile, check altert log for more info

Limiting Entries
Parameters that list a number for controlling implementation of a
feature of the Oracle9i server usually fall into one of two categories:
Resource limiters - How many resource items should be made available
to the instance upon startup. The entries open_cursors, open_links, and
timed_statistics fall into this realm.
Memory allocations - How much memory should be set aside for the
piece of functionality described by these entries. The most commonly
changed parameters in this class are db_cache_size, shared_pool_size,
and sort_area_size. Some of these entries accept k for kilobytes, m
for megabytes, and g for gigabytes; others simply accept an integer
number of bytes.
89/117

Oracle

pl/sql programming

There are some operating system -and Oracle9i -enforced minimums and
maximums that can be specified for these entries, and if they exist on your
hardware platform, you will be told when the instance is started. An occurrence
of this is shown in the next listing.
/d0/oraclehome/product/oracle9.0.1/dbs> sqlplus /nolog
SQL*Plus: Release 9.0.1.0.0. Production on Sun Jun 17 13:44:09 2009
( c ) Copyright 2001 Oracle Corporation . All rights reserved.
SQL> connect / as sysdba
Connected to an idle instance.
SQL> startup
ORA-00093: shared_pool_reserved_size must be between 5000 and 8388608
Feature Entries
Feature entries also fall into two categories:

Those that can only specify keywords like true, false, partial, or full. A
few parameters that fall into this category are max_dump_file_size,
oracle_trace_enabled, and row locking. Any values other than those in
the approved list for each parameter will be rejected, as shown next.

SQL>ORA-01078:failure in processing system parameters


LRM-00105: always is not a legal Boolean for oracle_trace_enable

Those that determines the level to which a feature is enabled. A good


example of this type of entry is compatible. As the version number of the
Oracle9i software increases , more and more newfangled functionality is
added. To leverage the new features, this parameter must be set to reflect
the new version number.
Before moving on to the control file, let us
spend a minutes on making changes to the parameter values in INIT.ora.

Making Changes to Parameters


Not all parameters in INIT.ora can be changed. Often, changes to the
INIT.ora are put in place to attempt to deal with performance issues. Sometimes
tuning books or the Oracle9i documentation suggests increasing the likes of
shared_pool_size or db_cache_size to assist the speed and throughput of the
database.
In earlier releases of the Oracle server, the only way to change parameter
values was to edit the INIT.ora file, shut down, and start up the database. Since
Oracle7, and more so with Oracle8 and Oracle9i, more and more changes can
be made with the database running. The v$parameter data dictionary view
90/117

Oracle

pl/sql programming

shown in the next listing is where you can deduce what parameters can be
changed without bouncing (shutdown followed by startup) the database.
SQL> desc v$parameter
Name
Null?
Type
------------------------------------------------------------NUM
NAME
TYPE
VALUE
ISDEFAULT
ISSES_MODIFIABLE
ISSYS_MODIFIABLE
ISMODIFIED
ISADJUSTED
DESCRIPTION
UPDATE_COMMENT

NUMBER
VARCHAR2(64)
NUMBER
VARCHAR2(512)
VARCHAR2(9)
VARCHAR2(5)
VARCHAR2(9)
VARCHAR2(10)
VARCHAR2(5)
VARCHAR2(64)
VARCHAR2(255)

You may now have a preliminary knowledge of INIT.ora , what this file is all
aboutThe Control File
Oracle9i builds a control file when a database is created; you require only
one control file per instance, but best practices dictate at least two of these
files, at all times. This file is a road map to the Oracle9i database and
contains instance-specific information such as

The name of the database.


Fully pathed names of all database files and redo log files.
The time and date that the database was created.
The current log sequence number -Oracle9i uses its online redo logs in a
circular fashion, allocating this sequence number at the start of a new log
file.
Relevant checkpoint information.
Control file information is available in the v$controlfile data
dictionary view. This view is shown below.

91/117

Oracle

pl/sql programming

SQL> desc v$controlfile


Name
STATUS
NAME

Null?

Type
VARCHAR2 (7)
VARCHAR2(513)

The startup and shutdown of the Oracle9i database uses the instance
control files for consistency and completeness checking. When we speak of
consistency, we refer to the cross-file dependencies all over the Oracle9i
database that are checked and rechecked on startup and shutdown. In this
context, completeness means a check for the presence of and accessibility to all
the files mentioned in the control files. Let us look now at the redo or transaction
logs.
Redo Logs
The redo log files are the heart of the proprietory Oracle9iserver. Some
other vendors may have a similar facility for tracking the activity against their
database. Oracle will write to any number of redo log files that the DBA chooses
to specify. Redo logs were introduced in Oracle V6 (circa 1988), and with
Oracle7 in February 1993, redo log files were enhanced to become multimembered redo log groups. When DBA now talk about the online redo logs,
they really mean online redo log groups.
When redo log groups are created, we give them an integer number,
which becomes the group number to which they are referred by the DBA. We
then speak of redo log group 1or redo log group 2, and so on. As users interact
with the Oracle9i database, a record of their activities is written to the online redo
logs at commit or rollback time. Redo logs are a finite size, and when they fill up,
Oracle switches to another set of log files.
NOTE
Each member of the same redo log group is a mirror image of the other
members in the same group.
Oracle9i needs at least two single-membered redo log groups to operate,
though we recommend at least three two-membered redo log groups. These
must be made manually using a GUI such as OEM or SQL*Plus. When a redo
log group fills up, Oracle switches to the next available group. Before a group is
marked available, Oracle marches through each redo log group reconciling any
outstanding activities, and then marks the group able to be used the next time a
switch occurs. The question you may have already asked yourself is What if a
group has not yet been marked as reusable and its turn comes up?. Oracle9i
suspends activity against the database until the group is marked reusable, and
92/117

Oracle

pl/sql programming

then operations carry on Figure 1 illustrates this concept

Group 2

Group 1

Group 3

.
Figure 1 -The circular re-use of the online redo log groups
Note
Online redo log file information can be viewed in the v$logfile data
dictionary view shown in the next listing.
SQL>desc v$logfile
Name
Nul?
Type
---------------------------------------------GROUP#
NUMBER
STATUS
VARCHAR2(7)
TYPE
VARCHAR2(7)
MEMBER
VARCHAR2(513)

We have now looked at the major players- background support


processes, redo logs, and control files, these files track activities and pertinent
information about the Oracle9i instance. Figure 2 illustrates who interacts with
what .
93/117

Oracle

pl/sql programming

FIGURE 2 - SGA , SUPPORT PRECESS AND FILE INTERACTION

reco
pmo
n

smon

Dbw0

SHARED
MEMORY
( SGA)

LGWR

R
ckpt

Data
files

Control
files

94/117

Arc0

Offline
Offline
storage
Offline
storage
Online
storage
redolog

Offline
storage

Oracle

pl/sql programming

The Database Data Files


Your data is stored in the data files. These O/S files are created using one
of the tools supplied with Oracle9i, be it SQL*Plus or OEM. Data files
themselves are not allocated to the database directly; they are hooked into the
instance using an Oracle9i tablespace. As tablespaces are created, one or
more data files are included, as shown in the next listing- as part of a create
tablespace command.
Create tablespace gl
datafile /do/oradata/ntirety/beg9/gl01.dbf size 2000m,
/d1/oradata/ntirety/beg9/gl02.dbf size 2000m,
/d2/oradata/ntirety/beg9/gl03.dbf size 2000m
blocksize 2048
default storage . . . ;
NOTE
When the block size keyword is used to create a table space, there must
be a corresponding parameter (in this case, db_2k_cache_size) in
INIT.ora for that sized block. If you include the block size keyword
without its corresponding size parameter, you will get error ORA_29339.
Once this command is written, an entry is written to DBA-DATA-FILES,
part of Oracle9i data dictionary, and the table space is acquired by the instance.
Table I illustrates the hierarchical relationship between the database, a table
space, and the database data files.
When a table space is added to an Oracle9i instance, a record of its size,
name, and location is written to the control files and the data dictionary. The
tablespace map in the data dictionary tracks the Oracle data blocks that have
been allocated to a tablespace. Once the file exists, space is available to users
with appropriate credentials. The Oracle9i create database statement produces
the SYSTEM tablespace where the data dictionary resides.
As soon as the database exists, the DBA runs a handful of administration
scripts that set up the remainder of the data dictionary. One use for table spaces
over and above SYSTEM is for Oracle9is rollback segments. A discussion of
architecture would be deficient without paying some attention to these
components of each and every Oracle database.
95/117

Oracle

pl/sql programming

Entity
Database
Tablespace
Data file

Is a superset of
Tablespace / data file
Datafile

Belongs to
Database
Tablespace

TABLE - I Relationship Between Database, Table space and Data file


Rollback Segments / Undo Tablespace
Whatever format you choose for the management of your databases
undo, that information plays a crucial role in the implementation of Oracles read
consistent mode. With multiple user sessions working with the data
concurrently, this model ensures that a session has access to column values
within a database table for the life cycle of the transaction. When necessary,
Oracle9i automatically saves a before image of data, in case the transaction
that initiated the change is not committed. Suppose a banking application is
receiving a deposit for $1,200 into a savings account with a current balance of
$940. The first try at the update, the operator enters 12,000 instead of 1200
Table2. illustrates how read consistency is imnplemented, assuming the session
that is performing the updates shown has a session identifier, or SID, of 99.
Account Balance at End of Activity
State

Activity

Undo

1
2

Pretransaction #1
Update savings set balance
= balance + 12000 where
account = 55524;
Rollback;
Update savings set balance
= Balance + 1200
where account = 55524;
Commit;

3
4
5

Empty
940

Data in
memory
940
12,940

Seen by
others
940
940

Empty
940

940
2,140

940
940

Empty

2,140

2140

TABLE -2 Read Consistency and the Role played by Undo


Notice how when SID 99 has no active transaction, there is no undo.
When the transaction started (state 2), Oracle9i allocates an undo area to keep a
copy of the pretransaction balance. Before the transaction started, the
96/117

Oracle

pl/sql programming

information for account 55524 was on disk, not having yet been read into
memory. As the transaction begins, the data is scooped into memory, the update
applied, and undo space reserved for the sake of other users. When the
rollback; is issued, the data that was supposed to have been updated is left in
memory, with its old value, and the undo released. It is the same story when the
transaction is reinitiated, and upon commit; the undo is released and the new
value, in memory, is available to SID 99 and all other sessions. The secret of this
read consistent model is illustrated in another way in Table 3 showing how the
concurrent user community sees the data in account 55524.
-------------------------------------------------------------------------------------------------Balance Value Seen and from Where
( D = database, M = Memory, U = undo)
State

SID 99

Other Sessions

1
940 (D)
940 (D)
2
12,940 (M)
940 (U)
3
940 (M)
940 (M)
4
2,140 ( M)
940 (U)
5
2.140 (M)
2,140 (M)
--------------------------------------------------------------------------------------------------TABLE - 3 Who Views What Value and from Where
The m word (memory) keeps surfacing in this section. Speaking of memory, let
us move on and look at two significant areas in shared memory -the library
cache and the data cache. The next section will just about round out the
discussion of Oracle9i architecture.
Significant Memory Structures
Oracle9i is a fabulous user of computer memory. Here, we are going to
have a look at the two most significant memory structures-the library cache and
the data cache.
The Data Cache
Oracle9i sets aside a portion of its SGA to hold data read from the
database files and / or getting ready to be written back to those same files. The
size of the data cache is determined by a handful of INIT.ora parameters, the
most common being db_cache_size. This entry specifies a default cache size in
megabytes (using m) or an absolute number of bytes.

97/117

Oracle

pl/sql programming

Figure 3 highlights how Oracle 9i uses its data cache. User sessions
read and manipulate data in this cache. They do not directly interact with the
database files. All data, regardless of what ends up happening to it, passes
through memory on its way to these user sessions.
Oracle9i deliberately uses memory to store data as it is massaged by the
user community. Printing, reading from disk drives, and memory access are
common activities performed as systems operate, listed from slowest to fastest.
One can justifiably claim that the speed with which the printer churns out the
printed word ,sets the standard for the speed of the computer. The point of all
this ? If you had a choice between reading Oracle9i data directly from disk or
memory, which would you choose- access at the speed of the printer or from
memory? Here is a hint- when read from memory, the access is virtually at the
speed of light, or 280,000 kilometers per second.
Oracle9i moves data into memory before making it accessible to user
sessions. These sessions work with the data in memory, the data gets marked
as changed, where appropriate, and eventually gets written back to disk.
Oracle9i performs all its data manipulation in the data cache, a finite amount of
computer memory.

USER SESSIONS
User sessions read data from
and return data to the data cache

Data cache

SGA

Library
cache

Background processes move data


between the data cache and the database
files
Oracle 9i database files

FIGURE 3 HOW ORACLE 9i USES THE DATA CACHE

98/117

Oracle

pl/sql programming

Cache sizes of 400MB to 500MB are common on some of the higher-end UNIX
Servers. Oracle9i manages the space in the data cache using a least recently
used, or LRU, algorithm. Data gets aged out of the cache when the space it
occupies is required for other data. The LRU rule ensures that data used the
longest time ago is flushed before the more active data. Once an Oracle9i
instance is started, you need not perform any manual maintenance of the data
cache
The Library Cache
The library cache is where all the SQL and PL/SQL statements reside in
memory. All theOracle9i database engine understands is SQL; regardless of
what you use to facilitate user interaction with the database. SQL is what gets
sent off to the software for processing. This cache is sized primarily by
shared_pool_size in INIT.ora, with absolute values in bytes or the megabyte
measurement followed by the m abbreviation. In a nutshell, the following steps
are how Oracle9i processes SQL:
Statement is passed to Oracle9i for processing.
.Before it is placed in the library cache, a hash value is computed that
represents a number of characteristics of the SQL.
Oracle compares the computed hash value against those values in a
hash table it maintains for SQL statements already in the cache.
If a match is found, the new SQL statement is thrown away and the one
sitting in the cache is executed on its behalf.
If no match is found, further processing is done on the new SQL
statement, and entry is made in the library cache hash table for the
newly arrived code, and it is placed in the library cache.
Any SQL statement executed against the Oracle9i database must first be
placed in the library cache and marked ready-to-execute. This library cache, is
also referred to as the shared pool.

Locks and Latches


Locks and latches are fundamental to the protection of your data and
shared memory structures. Oracle9i runs in a multi user environment, and

99/117

Oracle

pl/sql programming

without these protection mechanisms, the smooth and consistent operation of the
database would be in question.

Locks
Oracle9i uses locks to ensure that different sessions are not able to
interact with the same data in use by other sessions. Interact in this context
means anything other than select. This protects the integrity of the data and is
managed automatically by Oracle9i, without need for manual intervention. Locks
are acquired as SQL statements begin their interaction with data and last for the
duration of a transaction. Transactions commonly end with a commit or
rollback, the latter restoring data to its pre-transaction state. Oracle9i uses two
locking modes:
Exclusive mode will not allow the locked resource to be shared what-soever by any concurrent sessions. This lock is acquired to modify data or
define the structures within which data resides.
Share mode allows concurrent read access to the same chunk of data,
with escalation to an exclusive mode lock when change is initiated.
Oracle 9i obtains a share mode lock on a row of data as it is accessed as
part of the result set to a query. If, and only if, that query leads to an update or
delete statement, the lock is escalated to an exclusive row lock, if the row is not
already locked in that mode. Oracle9i allows simultaneous updates to rows
sitting in the same data block. If two sessions request update access to the
same row in the same data block, they queue up and go about their business in
a serial fashion. There are two types of locks Oracle9i acquires on its data;

DML locks, or data manipulation locks, ensure data integrity in multi- user
environments for the purposes of protecting data.
DDL locks, or data definition locks, protect the structure of objects and are
acquired for data definition activities.

Oracle9i requests a lock in the least restrictive mode possible and,


from time to time, may convert a number of row locks to a table lock to reduce
the number of locks being acquired. Oracle9i chooses this path when the
management of a table lock requires less overhead than the protection provided
by multiple row locks.
Latches
Latches are low-level mechanisms that help manage the internal
operations of the Oracle9i software. They can be thought of as a type of lock,
acquired and released in subsecond time periods . Latches are almost always
100/117

Oracle

pl/sql programming

obtained when requested , but, as the activity on an Oracle9i database


increases, often queue behind one another for getting hold of precious
resources. Remember the redo logs and how transaction information is written
to these files as the database operates. A special redo copy latch ensures that
one and only one process writes to the redo logs, at a time. Obtaining a latch is
only part of the work; there is a cleanup phase that comes into play as a latch is
released.
Latches are required when working with shared memory structures in the
SGA. If working with a particular structure requires a latch and that structure is in
use, a wait situation is created. There are two types of latches:

Willing to wait means that , if a latch cannot be obtained at once, a


persistent request is resubmitted until it can be satisfied. Latches in the
library cache are examples of ones that fall into this category.
Requests for no-wait latches are cancelled if the latch cannot be obtained
immediately and are resubmitted as a new request. Latches related to
redo log copies fall into this class.

DBA need not worry themselves about latches unless they cause
problems in their databases, if they ever do. Suffice it to say, latches are part
of the puzzle fundamental to the operation of the Oracle9i database and,
most of the time, go about their work unnoticed. They are an essential player
in the running of the instance . We find it almost ironic that the words lock and
latch both start with the same letter-/-and the words look out start with the
same letter, which is what you will do if your locks and latches lead to
significant wait situations. The hourglass displayed by the mouse cursor
when a window is busy is a familiar example of a wait situation.
We have given you a framework of how the Oracle9i database is
put together and what pieces play what role. Each component in the software
equation may not be all that important on its own; bring all of them together
and you have a powerful, robust, and fast database management system i.e.
Oracle9i.

101/117

Oracle

pl/sql programming

USER MANAGEMENT
The Oracle database has several layers of
security and gives you the ability to Audit each level.
Security Capabilities
Oracle makes several levels of security
available to the DBA.

Account security for validation of users.


Access security for database objects
System level security for managing global
privileges.

Account Security
In order to access data in an Oracle database,
you must have access to an account in that data base. Each
account must have a password associated with it. A database
account can also be tied to an operating system account.
Passwords are set for a user when the users account is
created and may be altered after the account is created.
A users ability to alter the account password
will be limited by the tools to which the user is granted access.
The data base stores an encrypted version of the password in
a Data Dictionary table. If the account is directly related to an
OS account, it is possible to by-pass the password check and
rely on the operating system authentication instead.
The passwords can expire and the DBA can
establish the conditions under which a password can be reused in a database setting for password history. You can use
profiles to enforce standards for the passwords and can
automatically lock accounts, if there are multiple consecutive
failure to connect to the account.
Object Privileges
102/117

Oracle

pl/sql programming

Access to objects within a database is enabled


via Privileges. These allow specific database commands to be
used against specific database objects via the Grant
Command
System Level Roles & Privileges
You can use roles to manage the system level
commands available to users. These commands include
CREATE TABLE and ALTER INDEX. The CONNECT and
RESOURCE Roles are useful for the basic system privileges
required by end users. Users who have the resource role are
also granted the unlimited table space system privilege.
Because of this additional privilege, you should restrict the use
of Resource role to development and test environments.
Implementing Security
The security capabilities in oracle include roles,
Profiles and direct grant of privileges. The Oracle Enterprise
Manager toolset provides a security Manager tool to enable
the management of user accounts, roles, privileges and
profiles.
Creating Users
When creating a user, your goal is to establish a
secure, useful account that has adequate privileges and
proper default settings. When the account is created, it will
not have any capabilities and users will not even be able to
login, until that privilege is granted.
All of the necessary settings for a user account
can be specified within a single create user command. These
settings include values for all of the parameters listed.
Create user using Create user SQL command
Create user
user_name
Identified by password / externally
Default tablespace tablespace_name
Temporary Tablespace tablespace_name
Profile Profile_name / DEFAULT
Quota Integer / Unlimited
On tablespace_name

103/117

Oracle

pl/sql programming
Password
Account

expire
lock /unlock;

Parameter
Username
Password

usage
- Name of the schema
-Password for the account, may
also be tied directly to the
OperatingSystem host
account name.
-For host-based authentication use
Identified externally.
- Identified Globally as for network
based authentication.
Default Tablespace
- Objects created in this scheme
are stored .
- This setting does not give the
user, right to create objects. It
only sets a default value
Temporary Tablespace - The table space in which
temporary segments are used
during sorting transactions Quota (on table
space)
- Allows the user to store objects
in the specified Tablespace upto
the total size specified as quota.
Profiles
- Assigns a profile to the user. If
none is specified, then the
Default profile is used. Profiles are
used to restrict the usage of
System resources and to enforce
password management rules.

Password
Account

- Pre-expire the password


- Sets the account to either
locked or unlocked.

NOTE:

You cannot set the default roles during


create.
Default profile settings are for all Resource
Consumption limits to be set to unlimited.
If no quotas are specified, the user cannot
create objects in the database.
104/117

Oracle

pl/sql programming

Users do not need space quotas on the


Temporary table space, in order for their
queries to create temporary segments
there.
Except for the username, all of the
parameters in the Create user command
can be altered with the ALTER USER
command.

ALTER USER
Modify the security settings for an existing
database user, to change the options associated with that
user. Options that can be changed through the Alter user
command are:

Password
OS Authentication
Default tablespace
Temporary tablespace
Quota for Tablespace
Profile
Default Roles

Modifications to the security settings for a


user do not affect current sessions, only subsequent sessions.

Changing the quota per tablespace either


reduces or increase space for a user.

Changing the quota to o revokes access


from the table space entirely.

Profiles are altered, if the DBA decides to


alter the limitations on system resources.

Roles should be assigned if a user changes


departments and requires different privileges for the new
departments tables.
SYNTAX:
ALTER USER

username

105/117

Oracle

pl/sql programming
IDENTIFIED
by password / externally
DEFAULT TABLESPACE tablespace_name
TEMPORARY TABLESPACE tablespace_name
QUOTA integer / unlimited ON tablespace_name
DEFAULT ROLE role_name /All except role/
None;
WHERE :
Default Role
Default Role
Default Role
Default Role
Default Role

- establishes default roles for


the user
rolename
all
all except rolename
none

The ALTER USER system privilege is required to alter the user.


Only options specified within the Alter user SQL command are
changed.
All previously given resources remain.
Once a quota of O is re-assigned, the objects owned by the
user remain in the revoked tablespace. Yet the objects cannot
be allocated any new space.
DROP AN EXISTING USER
Drop a data base user with the Drop user SQL command.
SYNTAX
DROP USER Username CASCADE;
WHERE
User user to drop
CASCADE drops all objects in the users schema before
dropping the user.
- When a user is dropped with the cascade option, the
username and associated schema are removed from the data
dictionary and all schema objects contained in the users
schema are immediately dropped.
- a user that is currently connected to a database cannot be
dropped.
- DROP USER system privilege is required to drop a user.
Monitor Users
106/117

Oracle

pl/sql programming

View user and profile information in the data


dictionary, which stores information about every username.
The data dictionary includes information on:
All users in the data base
The default tablespace for the tables, clusters
and indexes of each user.
The total space used for temporary segments
Space quotas.

Data Dictionary Views


The data dictionary for an Oracle database is a set of
tables and views that are used as a read only reference guide
of the database . The data dictionary views give up- to- date
information about users and objects.
Helpful data dictionary views
DBA _USERS
ALL_USERS
USER_USERS

DBA_PROFILES
DBA_TS_QUOTAS
USER_TS_QUOTAS

Example 1: Display information about all users of the database


with the DBA_USERS data dictionary view.
SELECT * from DBA_USERS;
Example 2:Display tablespace quotas for the current user with
the USER_TS_QUOTAS data dictionary view.
SELECT * from USER_TS_QUOTAS;
Kill a User session:
When necessary, terminate a users session while
that user is logged on to the database.
Killing a user session
Prevents a user from issuing further database calls.
Frees locked resources
Will display a message to the user

107/117

Oracle

pl/sql programming

Requires the ALTER SYSTEM privilege.

SYNTAX
ALTER SYSTEM kill session integer1, integer2;
Where:
Kill session terminates a session
Integer1
- specifies the user sessionid
Integer2
-specifies the user serial number
-A user session is killed when the user is holding resources
urgently needed by another user, or when the DBA needs to
shut down the database.
-

When a user session is killed, tasks performed are:


- Rolls back the users current transaction
- Release all currently held table on row locks.
- Frees all resources currently reserved for the user.
- If the user is performing some activity that must
be completed, such as waiting for a reply or rolling
back a transaction, the Oracle server waits for this
activity to complete.

Query the V$Session data dictionary view to identify the session


ID and serial number of user session.
SELECT SID, SERIAL#, username from V$session;
USER PROFILES
You can use profiles to place limits on the amount of
system and database resources available to a user and to
manage password restrictions. If no profiles are created in a
database ,then the default profile, which specifies unlimited
resources for all users will be used.
Resources that can be limited via profiles
SESSIONS_PER_USER

-Number of concurrent sessions


a user can have in an

instance

108/117

Oracle

pl/sql programming
CPU_PER_SESSION
hundredths

-The CPU time in


of seconds, that a session

can use
CPU_PER_CALL
hundredths of
CONNECT_TIME

- The CPU time in


seconds
- The number of minutes, a
session can be
a

connected to
database.
IDLE_TIME
connected to
database without being
actively used.
FAILED_LOGIN_ATTEMPTS

- The number of minutes, a


session can be
the
- The number of consecutive
failed login

attempts that
PASSWORD_LIFE_TIME
before
PASSWORD_REUSE_TIME
a password
used.
PASSWORD_REUSE_MAX

will cause an account to be


locked.
- The number of days a
password can be used
it expires.
- The number of days that
must pass before
can be re- The number of times a
password must be
before a

changed
password can be reused.
PASSWORD_LOCK_TIME
locked, if the
Login_ attempts
setting is exceeded.
PASSWORD_GRACE_TIME
during which a
can still be
when it has reached
password_life_time
settings

- The number of days an


account will be
failed_
- The length in days of the
grace period,
password
changed
its

109/117

Oracle

pl/sql programming

Eg:Create profile Limited_profile


Limit
Failed_ Login_ Attempts 5;
Create user sam
Identified by john
Profile limited_profile;
Password Management
You can use profiles to manage the expiration, reuse and complexity of passwords.

You can limit the life time of a password and lack


an account whose password in too old.
You can also force a password to be at least
moderately complex and lock an account that has
repeatedly failed login attempts . If you set the
failed_ login_ attempts resource of the users
profile to 5, then five consecutive failed login
attempts will be allowed for the account, the6th will
cause the account to be locked. If the correct
password is supplied on the fifth attempt, then the
failed-login-attempt count is reset to O, allowing
for 5 more consecutive unsuccessful login
attempts before the account is locked.
If an account becomes locked due to repeated
connection failures, it will automatically become
unlocked when it profiles password_lock_time
vale is exceeded. If password_lock_time is set to
1, then the account which is locked due to
repeated Connection failure would be locked for 1
day, at which point the account will be unlocked.
To unlock an account, use the account unlock clause of
the Alter user command from a DBA account.
ALTER USER sam account unlock;
-

can manually lock on account


ALTER USER sam account lock;

110/117

Oracle

pl/sql programming
You can establish a maximum life time for a
password via the Password_ life_time resource, within
profiles. You can force users to change their passwords every
30 days as in the following example.
CREATE PROFILE limited_profile
LIMIT
PASSWORD_LIFE_TIME 30;
CREATE USER sam
Identified by john
PROFILE limited_profile;
Each account that uses limited_ profile will
have its password expire after30 days. If you password has
expired, you must change it the next time you login, unless the
profile has a specified grace period for expired password. An
expired account requires manual intervention by the DBA, to
be re-enabled.
ALTER USER sam PASSWORD expire;
- when sam attempts to connect to his account next time, he is
immediately prompted for a new password for the account.
You can also force users to change their password
when they first access their account via the password expire
clause of the create user command.
To see the password expiration date of any
account, query the expiry_date column of the DBA_USERS
data dictionary and USER_USERS expiry- date column to see
the password expiration date of the account of the current
user.
PRIVILEGES
You can grant users privileges to access the
database and objects within the database and allow them
specific system privileges.
Privilege Type
1.

SystemPrivileges

111/117

Oracle

pl/sql programming
A privilege or a right to perform a particular action
or to perform a particular action on a particular type of object
2.

Object Privileges

A privilege or right to perform a particular action on


a specific table, view, sequence, procedure, function or
package.
System Privileges
Allows users to perform a particular database
operation or class of operation.
Types of system Privileges
1.

In ones own schema

The privilege to create a table , create a sequence in ones


own schema.
2.

On all objects of a specified type

Theprivilege to create a table in any schema or the


privilege to update rows in any table or view in any schema.
3.

On the System or a User.

The privilege to create a user or the privilege to


create a session.
Grant system Privileges
Grant system privileges to and from users and
roles using the Grant system Privileges.
Syntax
GRANT System Privilege / role
To user / role / PUBLIC
WITH ADMIN OPTION;
Where
Role
PUBLIC

is a role name to be granted


- grants system privileges/role to all
users.

112/117

Oracle

pl/sql programming
With Admn Option Allows the grantee to grant the system
Privilege or role to other users or
roles.
- Grants made with Admin option are not
hierarchical .
- Revoking a Grant with Admin option,
does not Cascade.
Display system Privileges
Example: List the system privileges that have been granted
By querying the view DBA_SYS_PRIVS.
SELECT * FROM DBA_SYS_PRIVS ;
Revoke system Privileges
Syntax:
REVOKE SYSTEM PRIVILEGE / ROLE
FROM USER /ROLE / PUBLIC;
Where
PUBLIC

- revokes the system privilege or role from all


users.

Object Privileges
Allows users to perform a particular action on a
specific table, view, sequence or stored procedures by
granting them object privileges. The type of object privileges
vary from object to object. Different object privileges allow the
use of specific SQL statements.

Object Privilege
SELECT
UPDATE
ALTER
DELETE
EXECUTE

SQL Statement Permitted


Select from Object (table, view)
Update object (table or view)
Alter object(table or sequence)
Delete from object
Execute object (Procedure/function)

113/117

Oracle

pl/sql programming
INDEX
REFERENCES

Create Index On Object (Tables only)


Create or Alter table statement
defining a Foreign key
Integrity constraint on object (tables
only)

- You can grant object privileges to users and roles with the
Grant command.
Syntax:
GRANT Object privilege / ALL [column]
ON Object TO user / Role / Public
WITH GRANT OPTION;
Where
Object Privilege
Column

- is an object privilege to be granted.


- Specifies a column from a table or view
on which privileges are

granted.
-Only specify columns when granting
Insert, References or update
privilege.

ALL
ON

-If columns are not listed, the grantee


has privileges on all columns
in the table or view.
-Specifies all object privileges.
-Identifies the object on which the
privileges are granted

TO

-Identifies users or roles to which the


object Privileges is granted.

PUBLIC

- grants to al users.

With grant

- allows the grantee to grant the object


Privileges to other users/roles

Grant option cannot be granted to a role


Example:
GRANT Select ON EMP TO Emi with Grant option;
Note:

114/117

Oracle

pl/sql programming
Emi can grant the privilege to another user or role.
Display object privileges
Select * from DBA_TAB_PRIVS;
Helpful Data Dictionary views
DBA_TAB_PRIVS

-Display all privileges on objects in the


Database.
DBA_COL_PRIVS -All privilege on Columns in the database.
USER_TAB_PRIVS
-All privileges on objects for which
the
User is the owner, grantor or grantee.
USER_COL_PRIVS
-Privileges on columns for which
the
user is the Owner, grantor or
grantee.
Revoke Object Privileges
Syntax
Revoke Object privilege on Object
From user / role / public
Cascade constraints;
Where
Cascade

drops any referential integrity constraints


defined using REFERENCES privilege.

Grantors can revoke privilege from only those users to


whom they have granted privileges.
Example;
REVOKE SELECT ON EMP
From Emi;
Revoke object privileges with Grant option, has a
cascading effect.
ROLES
Roles are named groups of related privileges that
are granted to users or other roles.
115/117

Oracle

pl/sql programming

Role characteristics
Can consist of both system and object privileges.
Are not owned by anyone, not in any schema
May be granted to any user or role
Can be enabled or disabled for each authorized user.
Description of roles are stored in the data dictionary.
Create Roles
Define categories of privileges for particular
groups of users by creating roles containing those privileges.
Create a role for each application (Application role)
Create a role for each type of user (User role)
Can GRANT user and application roles to users.
Syntax:
CREATE ROLE Role_name not identified / identified BY
password / externally;
Where
Role name
Not identified
required

- is the name of the role to be created


- Indicates that no password is
to Enable the role.

Identified

- Indicates that users granted the role


must be verified to enable it.
indicates that the user must
the password to

By password
specify
enable the role.
Externally
on operating

- ensures that the Oracle server verifies


user access to the Role using
system utility.

The CREATE ROLE PRIVILEGE IS REQUIRED TO


CREATE ROLES.
Example:
CREATE ROLE manager NOT identified;

116/117

Oracle

pl/sql programming
Grant create session, create any Table to
Manager;
Grant Manager to Emi;
Establish Default Roles
ALTER USER Username
DEFAULT ROLE rolename / all / all except
role_name /none;
- Default role :
-

establishes default roles for the user.

The Oracle server enables the users default roles at


login.
By default, all Roles granted to the user are Default
roles.
Helpful Data Dictionary views
ROLE_SYS_PRIVS
ROLE_TAB_PRIVS
ROLE_ROLE_PRIVS
SESSION_ROLES
USER_ROLE_PRIVS
DBA_ROLES

*********************

117/117

You might also like