Você está na página 1de 305

ORACLE

Course Material

Subhash Reddy Aedla


ORACLE

Database Management Systems


Database
A Database can be thought of as a set of logically related files organized to facilitate
access by one or more applications programs and to minimize data redundancy. In other
words, a database can be defined as a stored collection of data, organized on the basis
of relationships in the data rather than the convenience of storage structures. It is not a
replacement for files. Some general objectives in establishing a database are as follows.
1. Eliminate redundant data as much as possible.
2. Integrate existing data files.
3. Share data among all
4. Incorporate changes easily and quickly.
5. Simplify the use of data files.
6. Lower the cost of storing and retrieving data.
7. Improve accuracy and consistency.
8. Provide data security from unauthorized use.
9. Exercise central control over standards.
In addition to the database itself, a set of programs is necessary to facilitate adding new
data as well as modifying and retrieving existing data with is a database. This set of
programs is reffered to as a database management system (DBMS).
Specific Advantages of Database are
1. File Consolidation: Pooling data reduces redundancy and inconsistency and
promotes cooperation among different users. Since data base link records
together logically, a data change in one system will cascade through all the other
system using the data.
2. Program and File Independence: This feature separates the definition of the files
from their programs, allowing a programmer to concentrate as the logic of the
program instead of precisely how to store and retrieve data.
3. Access Versatility: User can retrieve data in many ways. They enjoy the best of
both worlds-sequential access for rapid data in a prescribed order and random
access for rapid retrieval of a specific record.
4. Data Security: Usually a DBMS includes password system that controls access to
sensitive data. By limiting their access to read –only write-only or specified

By Subhash Reddy Aedla Page 1 of 304


ORACLE

records, or were fields in records password can prevent certain users from
retrieving unauthorized data.
5. Program Development: Programmers must use standard names for data items
rather than invent their own from program to program. This allows the
programmer to focus on desired function.
6. Program Maintenance: Changes and repairs to a system are relatively easy.
7. Special Information: Special-purpose reports generators are produce reports
with minimum effort.

Database Management System


It is a set of programs that organizes and maintains the information. The primary
objective of DBMS is to provide convenient environmental to retrieve and store
database information. Database supports single user and multi user environmental.
While on DBMS permits only one person to access the database at a given time.
DBMS offers the following services:
a. Data Definition: It is the method of data definition and storage.
b. Data Maintenance: It checks whether each record has fields containing all
information about one particular item. For examples in an employee table, all
information about the employee like name, address, designation, salary, and
dept-name is recorded.
c. Data Manipulation: Allows data in the database to be inserted, updated,
deleted, and stored.
d. Data Display: This method helps in viewing data.
e. Data Integrity: This ensures the accuracy of the data.

Data Models
The structure of a database is the concept of a data model, a collection of conceptual
tools for describing data, data relationships and consistency constraints. The various
data models that have been proposed fall in to three different groups: object based
logical models, record based logical models, and physical data models.
Object based logical models are used in describing data at the conceptual and view
levels. There are many different models, some of the more widely known ones are:
 The entity relationship model
 The object oriented model

By Subhash Reddy Aedla Page 2 of 304


ORACLE

 Binary model
We examine the entity relationship model only.
The Entity Relationship (E-R) data model is based on a perception of a real world which
consists of a collection of basic objects called entities and relationships among these
objects. An entity is an object that is distinguishable from other objects by a specific set
of attributes. For example, the number and balance describe one particular account in a
bank. A relationship is an association among several entities. For example, a CustAcct
relationship associates a customer with each account that she or he has. The set of all
entities of the same type and relationships of the type are termed as antity set and
relationship set, respectively.
The over all logical structure of a database can be expressed graphically by an E-R
diagram, which consists of the following components.
 Rectangles, which represent entity sets.
 Ellipses, which represents attributes.
 Diamonds, which represent relationship among entity sets.
 Lines, which link attributes to entity sets and entity sets to relationships.

street
numbe balanc
name city r e

CustAc
account
customer
ct

Terms Related to Database:


Entity: An entity is an object, place, person, concept, or activity about which an
enterprise records data.
Entity types: The details of an entity such as name, price, desc etc are called entity
types.
Entity instances: The value given for entity types are termed as entity instances.
Attribute: It is the characteristic property of an existing entity.
Attribute type: It is property of entity type.
Attribute instances: It is the property of entity instance.

By Subhash Reddy Aedla Page 3 of 304


ORACLE

Relationship among data: A relationship is defined as “an association among entities”. A


relationship type is an association of entity types. A relationship may associate an entity
with itself. Several relationships may exist between the same entity and they are of
three types.
One to one relationship
One to many (or) many to one relationship
Many to many relationship
Record-Based Logical Models are used in describing data at the conceptual and view
levels. In contrast to object-based data models, they are used both to specify the overall
logical structure of the database and to provide a higher-level description of the
implementation.
The three most widely accepted data models are the relational, network and
hierarchichal models.
Network Model: Data in the network model are represented by collection of records
and relationships among data are represented by links, which can be viewed as pointers.
The records in the database are organized as collections of arbitrary graphs.

Johnson 192-83-7465 Alma Pal Alto A-101 500

Smith 019-28-3746 North Rye A-215 700

A-102 400
Hayes 677-89-9011 Main Harrison

A-305 350

Turner 182-73-6091 PutnamStamford A-201 900

Jones 321-12-3123 Main Harrison


A-222 700

Figure: A sample network database.

By Subhash Reddy Aedla Page 4 of 304


ORACLE

Disadvantages
1. The use of pointers leads to complexity in the structure. As a result of increased
complexity mapping of related data becomes very difficult.
Hierarchical Model: The hierarchical model is similar to the network model in the sense
that data and relationships among data are represented by records and links,
respectively. It differs from the network model in that the records are organized as
collections of trees rather than arbitrary graphs. It is also referred as tree structure. In
this method data is stored in the form of a parent – child relationship. The origin of data
tree is root. Data located at different levels along a particular branch from the root is
called the node. Each node may be subdivided into two or more additional nodes. The
last node in the series is called leaf. This method supports one to many relationship.
Disadvantages
1. It is not possible to enter any new level into the existing system, and to do this
entire structure has to be rearranged.
2. It does not support many to many relationships
Relational Models represents data and relationships among data by a collection of
tables, each of which has a number of columns with unique names. The following is a
sample relational database showing customers and the accounts they have.
Name Street City Number

Lowery Maple Queens 900

Shiver North Bronx 556

Shiver North Bronx 647

Hodges Sidehill Brooklyn 801

Hodges Sidehill Brooklyn 647

Number Balance

900 55

556 100000

647 10534

801 355676

RELATION: A table of values


 A relation may be thought of as a set of rows.

By Subhash Reddy Aedla Page 5 of 304


ORACLE

 A relation may alternately be thought of as a set of columns.


 Each row represents a fact that corresponds to a real-world entity or
relationship.
 Each row has a value of an item or set of items that uniquely identifies that row
in the table.
 Each column typically is called by its column name or column header or attribute
name.
A Relation may be defined in multiple ways.
The Schema of a Relation: R (A1, A2, .....An)
Relation schema R is defined over attributes A1, A2, .....An
For Example -
CUSTOMER (Cust-id, Cust-name, Address, Phone#)
Here, CUSTOMER is a relation defined over the four attributes Cust-id, Cust-name,
Address, Phone#, each of which has a domain or a set of valid values. For example, the
domain of Cust-id is 6 digit numbers.
 A tuple is an ordered set of values
 Each value is derived from an appropriate domain.
Each row in the CUSTOMER table may be referred to as a tuple in the table and would
consist of four values.
<632895, "John Smith", "101 Main St. Atlanta, GA 30332", "(404) 894-2000">
is a tuple belonging to the CUSTOMER relation.
 A relation may be regarded as a set of tuples (rows).
 Columns in a table are also called attributes of the relation.
 A domain has a logical definition: e.g.,
“USA_phone_numbers” are the set of 10 digit phone numbers valid in the U.S.
A domain may have a data-type or a format defined for it. The USA_phone_numbers
may have a format: (ddd)-ddd-dddd where each d is a decimal digit. E.g., Dates have
various formats such as monthname, date, year or yyyy-mm-dd, or dd mm,yyyy etc.
An attribute designates the role played by the domain. E.g., the domain Date may be
used to define attributes “Invoice-date” and “Payment-date”.

Informal Terms Formal Terms

By Subhash Reddy Aedla Page 6 of 304


ORACLE

Table Relation

Column Attribute/Domain

Row Tuple

Values in a column Domain

Table Definition Schema of a Relation

Types of Attributes
Simple and composite Attributes
Simple Attribute the one which cannot have the scope to divide in to small sub products
Composite attributes can be divided into smaller subparts. These subparts represent
basic attributes with independent meanings of their own. For example, take Name, we
can divide it into sub-parts like First name, Middle name, and Last name.
Single-valued and multi-valued attributes
Attributes that can have single value at a particular instance of time are called single
valued. A person can’t have more than one age value. Therefore, age of a person is a
single-values attribute.
A multi-valued attribute can have more than one value at one time. For example, degree
of a person is a multi-valued attribute since a person can have more than one degree.
Derived or Stored Attributes
The attribute from which another attribute value is derived is called derived or stored
attribute.

By Subhash Reddy Aedla Page 7 of 304


ORACLE

There may be a case when two or more attributes values are related. Take the example
of age. Age of a person can be calculated from person’s date of birth and present date.
Difference between the two gives the value of age. In this case, age is the derived
attribute.

Key Attributes
Primary Key – An attribute that is used by the database designer for unique
identification of each row in a table is known as Primary Key.
Secondary Key – An Attribute other than primary key that is used for identification of
each row in a table is known as secondary key or an alternate key.
Super Key – When a Primary key is defined with a combination of two or more
attributes for unique identification of each row in a table is known as Super key
Candidate Key – The sub set of a super key is called as a candidate key and it is used to
verify the functional dependency of non key attributes (to be discussed in Normalization
session)
Foreign Key – A foreign key is an attribute or combination of attribute in one base table
that points to the candidate key (generally it is the primary key) of another table. The
purpose of the foreign key is to ensure referential integrity of the data i.e. Only values
that are supposed to appear in the database are permitted. It is also called as Reference
Key

Relational Database Management System


Dr. Edgar F. Codd first introduced the relational database model in 1970. It organizes the
data in terms of two dimensional tables that is simple rows and columns format and
differently markedly from their hierarchical and network computers. In a relational
database management system, we have the same concept of files, records, and fields.
Files are represented in two dimensional tables, each of which is called a “relational”.
Records which can be visualized as rows in a table are called “tuples”. Fields can be
visualized as a columns, and are called by attribute names or
A relational DBMS can perform the following basic operations.
 Create or delete tables
 Update, insert, or delete rows
 Add or delete columns
 Copy data from one table to another
 Retrieve or query a table, row or column

By Subhash Reddy Aedla Page 8 of 304


ORACLE

 Print, recognize, or read a table or row


 Join or combine tables based on a value in table
Disadvantages
1. The major disadvantage is that clear cut interface cannot be determined.
2. Reusability of structure is not possible.
3. Maintainance of relational structure becomes a contentious issue at times.
RDBMS is now an accepted model on which major database systems are built. Oracle
has introduced added functionality to this by incorporating object oriented capabilities,
and hence now it is known as object relational database management system.
Object Relational Database Model
It supports both object oriented and relational concepts. It eliminates certain
discrepancies in the relational model. In this model it is possible to provide well defined
interfaces for applications. A structure once created can be reused this is the
fundamental property of the OOP's concept. By combining the object oriented and
relational concepts Oracle now offers best of both worlds.

E.F. Codd’s Rules


Dr. Edgar F. Codd is a fellow of IBM, had introduced the DBMS concepts for the first
time. He defined the first three normal forms for data and was responsible for the
development of language neutral interface to a relational database. He was the
originator of relational model; relational algebra and relational calculus. He created a
language named sequel (Sequential Query Language), which formed as a base for
introduction of SQL. SQL is the world wide acceptable language through which database
data manipulation is done
In 1985 Codd published a list of rules (which has since been expanded by others) that
became a standard way of evaluating a relational system. After publishing the original
article Codd stated that there are no systems that will satisfy every rule. Nevertheless
the rules represent the relational ideal and remain a goal for relational database
designers.
1) The Information Rule: All information in a relational database is represented
explicitly at the logical level in exactly one way - by values in tables.
2) Guaranteed Access Rule: Each and every datum (atomic value) in a relational
database is guaranteed to be logically accessible by resorting to a table name,
primary key value, and column name.

By Subhash Reddy Aedla Page 9 of 304


ORACLE

3) Systematic Treatment of Null Values: Null values (distinct from empty character
string or a string of blank characters and distinct from zero or any other number) are
supported in the fully relational DBMS for representing missing information in a
systematic way, independent of data type.
4) Dynamic On-line Catalog Based on the Relational Model: The database description
is represented at the logical level in the same way as ordinary data, so authorized
users can apply the same relational language to its interrogation as they apply to
regular data.
5) Comprehensive Data Sublanguage Rule: A relational system may support several
languages and various modes of terminal use (for example, the fill-in-blanks mode).
However, there must be at least one language whose statements are expressible,
per some well-defined syntax, as character strings and whose ability to support all of
the following is comprehensible: data definition, view definition, data manipulation
(interactive and by program), integrity constraints, and transaction boundaries
(begin, commit, and rollback). In practice all commercial relational databases use
forms of the standard SQL (Structured Query Language) as their supported
comprehensive language.
6) View Updating Rule: All views that are theoretically updateable are also updateable
by the system.
7) High-level Insert, Update, and Delete: The capability of handling a base relation or a
derived relation as a single operand applies nor only to the retrieval of data but also
to the insertion, update, and deletion of data.
8) Physical Data Independence: Application programs and terminal activities remain
logically unimpaired whenever any changes are made in either storage
representation or access methods.
9) Logical Data Independence: Application programs and terminal activities remain
logically unimpaired when information preserving changes of any kind that
theoretically permit unimpairment are made to the base tables.
10) Integrity Independence: Integrity constraints specific to a particular relational
database must be definable in the relational data sublanguage and storable in the
catalogue, not in the application programs.
A minimum of the following two integrity constraints must be supported:
a. Entity integrity: No components of a primary key are allowed to have a null
value.

By Subhash Reddy Aedla Page 10 of 304


ORACLE

b. Referential integrity: For each distinct non-null foreign key value in a relational
database, there must exist a matching primary key value from the same domain.
11) Distribution Independence: A relational DBMS has distribution independence.
Distribution independence implies that users should not have to be aware of
whether a database is distributed.
12) Non-subversion Rule: If a relational system has a low-level (single-record-at-a-time)
language, that low-level language cannot be used to subvert or bypass the integrity
rules or constraints expressed in the higher-level (multiple-records-at-a-time)
relational language.
Note: There is a rider to these 12 rules known as Rule Zero: "For any system that is
claimed to be a relational database management system, that system must be able to
manage data entirely through capabilities."

By Subhash Reddy Aedla Page 11 of 304


ORACLE

Normalization
Normalization is the process of organizing data in a database. This includes creating
tables and establishing relationships between those tables according to rules designed
both to protect the data and to make the database more flexible by eliminating
redundancy and inconsistent dependency.
Redundant data wastes disk space and creates maintenance problems. If data that exists
in more than one place must be changed, the data must be changed in exactly the same
way in all locations. A customer address change is much easier to implement if that data
is stored only in the Customers table and nowhere else in the database.
What is an "inconsistent dependency"? While it is intuitive for a user to look in the
Customers table for the address of a particular customer, it may not make sense to look
there for the salary of the employee who calls on that customer. The employee's salary
is related to, or dependent on, the employee and thus should be moved to the
Employees table. Inconsistent dependencies can make data difficult to access because
the path to find the data may be missing or broken.
There are a few rules for database normalization. Each rule is called a "normal form." If
the first rule is observed, the database is said to be in "first normal form." If the first
three rules are observed, the database is considered to be in "third normal form."
Although other levels of normalization are possible, third normal form is considered the
highest level necessary for most applications.
As with many formal rules and specifications, real world scenarios do not always allow
for perfect compliance. In general, normalization requires additional tables and some
customers find this cumbersome. If you decide to violate one of the first three rules of
normalization, make sure that your application anticipates any problems that could
occur, such as redundant data and inconsistent dependencies.
Normalization is a design technique that is widely used as a guide in designing relational
databases. Normalization is essentially a two step process that puts data into tabular
form by removing repeating groups and then removes duplicated data from the
relational tables.
Normalization is a body of rules addressing analysis and conversion of data structures
into relations that exhibit more desirable properties of internal consistency, minimal
redundancy and maximum stability. If a normalized design were converted, without any
change to the physical model, it would have the following properties: -
 Data storage requirements would be minimized since the normalization process
systematically removes duplication of data.

By Subhash Reddy Aedla Page 12 of 304


ORACLE

 Since data items are stored in the minimum number of places, the chances of
data inconsistencies would be minimized.
 Normalization structures would be optimal for updates (insert, update and
delete) at the expense of retrieval. Since data items exist at the minimal number
of places, an update operation (insert, update and delete) would need to access
the minimum amount of data.
Edgar F. Codd originally established three normal forms: 1NF, 2NF and 3NF. There are
now others that are generally accepted, but 3NF is sufficient for most practical
applications. Normalizing beyond that point rarely yields enough benefit to warrant the
added complexity.
Functional Dependencies
The concept of functional dependencies is the basis for the first three normal forms. A
column, Y, of the relational table R is said to be functionally dependent upon column X
of R if and only if each value of X in R is associated with precisely one value of Y at any
given time. X and Y may be composite. Saying that column Y is functionally dependent
upon X is the same as saying the values of column X identify the values of column Y. If
column X is a primary key, then all columns in the relational table R must be functionally
dependent upon X.
In the example
Stud_Code Stud_Name Address
K105 Smith 501, Down Street, Los Angels
K106 Martin 811, Berkeley Gardens, Boston
the attribute Stud_Name is functionally dependent on the attribute Stud_Code, because
a value of the later determines the value of the former. Similarly, Address is also
functionally dependent on Stud_Code.
Full functional dependency applies to tables with composite keys. Column Y in
relational table R is fully functional on X of R if it is functionally dependent on X and not
functionally dependent upon any subset of X. Full functional dependence means that
when a primary key is composite, made of two or more columns, then the other
columns must be identified by the entire key and not just some of the columns that
make up the key.
We now proceed with the rules of normalization.
The following descriptions include examples.

By Subhash Reddy Aedla Page 13 of 304


ORACLE

First Normal Form


• Eliminate repeating groups in individual tables.
• Create a separate table for each set of related data.
• Identify each set of related data with a primary key.
Do not use multiple fields in a single table to store similar data. For example, to track an
inventory item that may come from two possible sources, an inventory record may
contain fields for Vendor Code 1 and Vendor Code 2.
What happens when you add a third vendor? Adding a field is not the answer; it
requires program and table modifications and does not smoothly accommodate a
dynamic number of vendors. Instead, place all vendor information in a separate table
called Vendors, then link inventory to vendors with an item number key, or vendors to
inventory with a vendor code key.
Second Normal Form
• Create separate tables for sets of values that apply to multiple records.
• Relate these tables with a foreign key.
Records should not depend on anything other than a table's primary key (a compound
key, if necessary). For example, consider a customer's address in an accounting system.
The address is needed by the Customers table, but also by the Orders, Shipping,
Invoices, Accounts Receivable, and Collections tables. Instead of storing the customer's
address as a separate entry in each of these tables, store it in one place, either in the
Customers table or in a separate Addresses table.
Third Normal Form
• Eliminate fields that do not depend on the key.
Values in a record that are not part of that record's key do not belong in the table. In
general, any time the contents of a group of fields may apply to more than a single
record in the table, consider placing those fields in a separate table.

For example, in an Employee Recruitment table, a candidate's university name and


address may be included. But you need a complete list of universities for group mailings.
If university information is stored in the Candidates table, there is no way to list
universities with no current candidates. Create a separate Universities table and link it
to the Candidates table with a university code key.

By Subhash Reddy Aedla Page 14 of 304


ORACLE

EXCEPTION: Adhering to the third normal form, while theoretically desirable, is not
always practical. If you have a Customers table and you want to eliminate all possible
interfiled dependencies, you must create separate tables for cities, ZIP codes, sales
representatives, customer classes, and any other factor that may be duplicated in
multiple records. In theory, normalization is worth pursing. However, many small tables
may degrade performance or exceed open file and memory capacities.
It may be more feasible to apply third normal form only to data that changes frequently.
If some dependent fields remain, design your application to require the user to verify all
related fields when any one is changed.
Other Normalization Forms
Fourth normal form, also called Boyce Codd Normal Form (BCNF), and fifth normal form
do exist, but are rarely considered in practical design. Disregarding these rules may
result in less than perfect database design, but should not affect functionality.
Normalizing an Example Table
These steps demonstrate the process of normalizing a fictitious student table.
1. Unnormalized table:
Student# Advisor Adv-Room Class1 Class2 Class3
1022 Jones 412 101-07 143-01 159-02
4123 Smith 216 201-01 211-02 214-01
2. First Normal Form: No Repeating Groups
Tables should have only two dimensions. Since one student has several classes, these
classes should be listed in a separate table. Fields Class1, Class2, and Class3 in the above
records are indications of design trouble.
Spreadsheets often use the third dimension, but tables should not. Another way to look
at this problem is with a one-to-many relationship, do not put the one side and the
many side in the same table. Instead, create another table in first normal form by
eliminating the repeating group (Class#), as shown below:
Student# Advisor Adv-Room Class#
1022 Jones 412 101-07
1022 Jones 412 143-01
1022 Jones 412 159-02

By Subhash Reddy Aedla Page 15 of 304


ORACLE

4123 Smith 216 201-01


4123 Smith 216 211-02
4123 Smith 216 214-01
3. Second Normal Form: Eliminate Redundant Data
Note the multiple Class# values for each Student# value in the above table. Class# is not
functionally dependent on Student# (primary key), so this relationship is not in second
normal form.
The following two tables demonstrate second normal form:
Students:
Student# Advisor Adv-Room
1022 Jones 412
4123 Smith 216
Registration:
Student# Class#
1022 101-07
1022 143-01
1022 159-02
4123 201-01
4123 211-02
4123 214-01
4. Third Normal Form: Eliminate Data Not Dependent On Key
In the last example, Adv-Room (the advisor's office number) is functionally dependent
on the Advisor attribute. The solution is to move that attribute from the Students table
to the Faculty table, as shown below:
Students:
Student# Advisor
1022 Jones
4123 Smith
Faculty:

By Subhash Reddy Aedla Page 16 of 304


ORACLE

Name Room Dept


Jones 412 42
Smith 216 42
The Problem: Keeping Track of a Stack of Invoices
Consider a typical invoice (Figure A). It has been simplified to meet the purposes of this
discussion.
This document, or something like it, is the basis of the order fulfillment process of
almost any business. Every piece of information you see here is important. How can we
capture this information in a database?
Figure A: Invoice

Those of us who have an ordered mind but aren't quite aware of relational databases
might try to capture the Invoice data in a spreadsheet, such as Microsoft Excel.
Figure A-1: orders spreadsheet

By Subhash Reddy Aedla Page 17 of 304


ORACLE

This isn't a bad approach, since it records every purchase made by every customer. But
what if you started to ask complicated questions, such as:
 How many 3" Red Freens did Freens R Us order in 2002?
 What are total sales of 56" Blue Freens in the state of Texas?
 What items were sold on July 14, 2003?
As the spreadsheet grows it becomes increasingly difficult to ask the spreadsheet these
questions. In an attempt to put the data into a state where we can reasonably expect to
answer such questions, we begin the normalization process.
First Normal Form: No Repeating Elements or Groups of Elements
Take a look at rows 2, 3 and 4 on the spreadsheet in Figure A-1. These represent all the
data we have for a single invoice (Invoice #125).
In database lingo, this group of rows is referred to as a single database row. Never mind
the fact that one database row is made up here of three spreadsheet rows: It's an
unfortunate ambiguity of language. Academic database theoreticians have a special
word that helps a bit with the ambiguity: they refer to the "thing" encapsulated by rows
2, 3 and 4 as a tuple (pronounced tu'ple or too'ple). We're not going to use that word
here (and if you're lucky, you'll never hear it again for the rest of your life). Here, we will
refer to this entity as a row.
So, First Normal Form (NF1) wants us to get rid of repeating elements. What are those?
Again we turn our attention to the first invoice (#125) in Figure A-1. Cells H2, H3, and H4
contain a list of Item ID numbers. This is a column within our first database row.
Similarly, I2-I4 constitute a single column; same with J2-J4, K2-K4, L2-L4, and M2-M4.
Database columns are sometimes referred to as attributes (rows/columns are the same
as tuples/attributes).
You will notice that each of these columns contains a list of values. It is precisely these
lists that NF1 objects to: NF1 abhors lists or arrays within a single database column. NF1
craves atomicity: the indivisibility of an attribute into similar parts.

By Subhash Reddy Aedla Page 18 of 304


ORACLE

Therefore it is clear that we have to do something about the repeating item information
data within the row for Invoice #125. On Figure A-1, that is the following cells:
 H2 through M2
 H3 through M3
 H4 through M4
Similar (though not necessarily identical) data repeats within Invoice #125's row. We can
satisfy NF1's need for atomicity quite simply: by separating each item in these lists into
its own row.
Figure A-2: flattened orders spreadsheet

I can hear everyone objecting: We were trying to reduce the amount of duplication, and
here we have introduced more! Just look at all that duplicated customer data!
Don't worry. The kind of duplication that we introduce at this stage will be addressed
when we get to the Third Normal Form. Please be patient; this is a necessary step in the
process.
We have actually only told half the story of NF1. Strictly speaking, NF1 addresses two
issues:
1. A row of data cannot contain repeating groups of similar data (atomicity); and
2. Each row of data must have a unique identifier (or Primary Key).
We have already dealt with atomicity. But to make the point about Primary Keys, we
shall bid farewell to the spreadsheet and move our data into a relational database
management system (RDBMS). Here we shall use Microsoft Access to create the orders
table, as in Figure B:
Figure B: orders table

By Subhash Reddy Aedla Page 19 of 304


ORACLE

This looks pretty much the same as the spreadsheet, but the difference is that within an
RDBMS we can identify a primary key. A primary key is a column (or group of columns)
that uniquely identifies each row.
As you can see from Figure B, there is no single column that uniquely identifies each
row. However, if we put a number of columns together, we can satisfy this requirement.
The two columns that together uniquely identify each row are order_id and item_id: no
two rows have the same combination of order_id and item_id. Therefore, together they
qualify to be used as the table's primary key. Even though they are in two different table
columns, they are treated as a single entity. We call them concatenated.
A value that uniquely identifies a row is called a primary key.
When this value is made up of two or more columns, it is referred to as a concatenated
primary key.
The underlying structure of the orders table can be represented as Figure C:
We identify the columns that make up the primary key with the PK notation. Figure C is
the beginning of our Entity Relationship Diagram (or ERD).
Our database schema now satisfies the two requirements of First Normal Form:
atomicity and uniqueness. Thus it fulfills the most basic criterion of a relational
database.
What's next?
Figure C: orders table structure

By Subhash Reddy Aedla Page 20 of 304


ORACLE

Second Normal Form: No Partial Dependencies on a Concatenated Key


Next we test each table for partial dependencies on a concatenated key. This means
that for a table that has a concatenated primary key, each column in the table that is
not part of the primary key must depend upon the entire concatenated key for its
existence. If any column only depends upon one part of the concatenated key, then we
say that the entire table has failed Second Normal Form and we must create another
table to rectify the failure.
Still not clear? To try and understand this, let's take apart the orders table column by
column. For each column we will ask the question,
Can this column exist without one or the other part of the concatenated primary key?
If the answer is "yes" — even once — then the table fails Second Normal Form.
Refer to Figure C again to remind us of the orders table structure.
First, recall the meaning of the two columns in the primary key:
 order_id identifies the invoice that this item comes from.
 item_id is the inventory item's unique identifier. You can think of it as a
part number, inventory control number, SKU, or UPC code.
We don't analyze these columns (since they are part of the primary key). Now consider
the remaining columns...
order_date is the date on which the order was made. Obviously it relies on order_id; an
order date has to have an order, otherwise it is only a date. But can an order date exist
without an item_id?

By Subhash Reddy Aedla Page 21 of 304


ORACLE

The short answer is yes: order_date relies on order_id, not item_id. Some of you might
object, thinking that this means you could have a dated order with no items (an empty
invoice, in effect). But this is not what we are saying at all: All we are trying to establish
here is whether a particular order on a particular date relies on a particular item.
Clearly, it does not. The problem of how to prevent empty orders falls under a
discussion of "business rules" and could be resolved using check constraints or
application logic; it is not an issue for Normalization to solve.
Therefore: order_date fails Second Normal Form.
Our table has already failed Second Normal Form. But let's continue with testing the
other columns. We have to find all the columns that fail the test, and then we do
something special with them.
customer_id is the ID number of the customer who placed the order. Does it rely on
order_id? No: a customer can exist without placing any orders. Does it rely on item_id?
No: for the same reason. This is interesting: customer_id (along with the rest of the
customer_* columns) does not rely on either member of the primary key. What do we
do with these columns?
We don't have to worry about them until we get to Third Normal Form. We mark them
as "unknown" for now.
item_description is the next column that is not itself part of the primary key. This is the
plain-language description of the inventory item. Obviously it relies on item_id. But can
it exist without an order_id?
Yes! An inventory item (together with its "description") could sit on a warehouse shelf
forever, and never be purchased... It can exist independent of an order.
item_description fails the test.
item_qty refers to the number of items purchased on a particular invoice. Can this
quantity exist without an item_id? Impossible: we cannot talk about the "amount of
nothing" (at least not in database design). Can the quantity exist without an order_id?
No: a quantity that is purchased with an invoice is meaningless without an invoice. So
this column does not violate Second Normal Form: item_qty depends on both parts of
our concatenated primary key.
item_price is similar to item_description. It depends on the item_id but not on the
order_id, so it does violate Second Normal Form.
item_total_price is a tricky one. On the one hand, it seems to depend on both order_id
and item_id, in which case it passes Second Normal Form. On the other hand, it is a

By Subhash Reddy Aedla Page 22 of 304


ORACLE

derived value: it is merely the product of item_qty and item_price. What to do with this
field?
In fact, this field does not belong in our database at all. It can easily be reconstructed
outside of the database proper; to include it would be redundant (and could quite
possibly introduce corruption). Therefore we will discard it and speak of it no more.
Figure C:

order_total_price, the sum of all the item_total_price fields for a particular order, is
another derived value. We discard this field too.
Here is the markup from our NF2 analysis of the orders table:
Figure C (revised):

By Subhash Reddy Aedla Page 23 of 304


ORACLE

What do we do with a table that fails Second Normal Form, as this one has? First we
take out the second half of the concatenated primary key (item_id) and put it in its own
table.
All the columns that depend on item_id - whether in whole or in part - follow it into the
new table. We call this new table order_items (see Figure D).
The other fields - those that rely on just the first half of the primary key (order_id) and
those we aren't sure about - stay where they are.
Figure D: orders and order_items tables

There are several things to notice:


1. We have brought a copy of the order_id column over into the order_items table.
This allows each order_item to "remember" which order it is a part of.
2. The orders table has fewer rows than it did before.
3. The orders table no longer has a concatenated primary key. The primary key
now consists of a single column, order_id.
4. The order_items table does have a concatenated primary key.
Here is the table structure (Figure E):
If you are new to Entity Relationship Diagrams, pay close attention to the line that
connects these two tables. This line means, in English,
 each order can be associated with any number of order-items, but at least one;

By Subhash Reddy Aedla Page 24 of 304


ORACLE

 each order-item is associated with one order, and only one.


There are other ways of depicting these table-to-table relationships; here I am using one
of many standard conventions.
Figure E: orders and order_items table structure

Second Normal Form: Phase II


But wait, there's more!
Remember, NF2 only applies to tables with a concatenated primary key. Now that
orders has a single-column primary key, it has passed Second Normal Form.
Congratulations!
order_items, however, still has a concatenated primary key. We have to pass it through
the NF2 analysis again, and see if it measures up. We ask the same question we did
before:
Can this column exist without one or the other part of the concatenated primary key?
First, refer to Figure F, to remind us of the order_items table structure.
Now consider the columns that are not part of the primary key...
item_description relies on item_id, but not order_id. So (surprise), this column once
again fails NF2.
item_qty relies on both members of the primary key. It does not violate NF2.
item_price relies on the item_id but not on the order_id, so it does violate Second
Normal Form.

By Subhash Reddy Aedla Page 25 of 304


ORACLE

Figure F:

We should be getting good at this now...


Figure F (revised):

...Take the fields that fail NF2, and create a new table. We call this new table items:
But wait, something's wrong. When we did our first pass through the NF2 test, we took
out all the fields that relied on item_id and put them into the new table. This time, we
are only taking the fields that failed the test: in other words, item_qty stays where it is.
Why? What's different this time?
The difference is that in the first pass, we removed the item_id key from the orders
table altogether, because of the one-to-many relationship between orders and order-
items. Therefore the item_qty field had to follow item_id into the new table.
In the second pass, item_id was not removed from the order_items table because of
the many-to-one relationship between order-items and items. Therefore, since item_qty
does not violate NF2 this time, it is permitted to stay in the table with the two primary
key parts that it relies on.
Figure G: order_items and items table

By Subhash Reddy Aedla Page 26 of 304


ORACLE

This should be clearer with a new ERD. Here is how the items table fits into the overall
database schema:
The line that connects the items and order_items tables means the following:
 Each item can be associated with any number of lines on any number of invoices,
including zero;
 each order-item is associated with one item, and only one.
Figure H:

These two lines are examples of one-to-many relationships. The whole three-table
structure, considered as a whole, is how we express a many-to-many relationship:
Each order can have many items; each item can belong to many orders.
Notice that this time, we did not bring a copy of the order_id column into the new table.
This is because individual items do not need to have knowledge of the orders they are
part of. The order_items table takes care of remembering this relationship via the
order_id and item_id columns. Taken together these columns comprise the primary key
of order_items, but taken separately they are foreign keys or pointers to rows in other
tables. More about foreign keys when we get to Third Normal Form.
Notice, too, that our new table does not have a concatenated primary key, so it passes
NF2. At this point, we have succeeded in attaining Second Normal Form!

By Subhash Reddy Aedla Page 27 of 304


ORACLE

Third Normal Form: No Dependencies on Non-Key Attributes


At last, we return to the problem of the repeating Customer information. As our
database now stands, if a customer places more than one order then we have to input
all of that customer's contact information again. This is because there are columns in
the orders table that rely on "non-key attributes".
To better understand this concept, consider the order_date column. Can it exist
independent of the order_id column? No: an "order date" is meaningless without an
order. order_date is said to depend on a key attribute (order_id is the "key attribute"
because it is the primary key of the table).
What about customer_name — can it exist on its own, outside of the orders table?
Yes. It is meaningful to talk about a customer name without referring to an order or
invoice. The same goes for customer_address, customer_city, and customer_state.
These four columns actually rely on customer_id, which is not a key in this table (it is a
non-key attribute).
These fields belong in their own table, with customer_id as the primary key (see
Figure I).
However, you will notice in Figure I that we have severed the relationship between the
orders table and the Customer data that used to inhabit it.
This won't do at all.
Figure I:

By Subhash Reddy Aedla Page 28 of 304


ORACLE

We have to restore the relationship by creating an entity called a foreign key (indicated
in our diagram by (FK)) in the orders table. A foreign key is essentially a column that
points to the primary key in another table. Figure J describes this relationship, and
shows our completed ERD:
The relationship that has been established between the orders and customers table
may be expressed in this way:
 each order is made by one, and only one customer;
 each customer can make any number of orders, including zero.
Figure J:

And finally, here is what the data in each of the four tables looks like. Notice that NF3
removed columns from a table, rather than rows.

By Subhash Reddy Aedla Page 29 of 304


ORACLE

Figure K:

By Subhash Reddy Aedla Page 30 of 304


ORACLE

EXERCISE
Normalize the following database and design the logical relations:
1. Employee Code
2. Employee First Name
3. Employee Surname
4. Department Code
5. Job Title
6. Sex
7. Grade Code
8. Grade Description
9. Minimum Basic
10. Maximum Basic
11. Increment Step
12. Current Basic
13. Department Name
14. Department Location
15. Year of Birth
16. Year of Joining
17. Boss’s Employee Code
18. Training Course Code
19. Training Topic
20. Training Duration in Days
21. Training Year
22. Training Cost
Note: Fields 18 to 22 repeated as many times as the number of training
programs attended by an employee.

By Subhash Reddy Aedla Page 31 of 304


ORACLE

Introduction to Oracle
Origin of the name ORACLE
IBM is an abbreviation for International Business Machines and SUN is an acronym for
Stanford University Network (or Networking). However, the word ORACLE is neither an
abbreviation nor an acronym (see an English dictionary for the meaning of the word
oracle). It appears in uppercase because this is the branding style Oracle Corp. chose for
itself.
The word Oracle means:
Prophecy or prediction; answer to a question believed to come from the gods; a
statement believed to be infallible and authoritative; a shrine at which these
answers are given
There is, however, more to the word Oracle: used for the name of the database engine,
and then later for the company itself. Larry Ellison and Bob Miner were working on a
consulting project for the CIA (Central Intelligence Agency in USA) where the CIA wanted
to use this new SQL language that IBM had written a white paper about. The code name
for the project was Oracle (the CIA saw this as the system to give all answers to all
questions or something such ;-).
The project eventually died (of sorts) but Larry and Bob saw the opportunity to take
what they had started and market it. So they used that project's codename of Oracle to
name their new RDBMS engine. Funny thing is, that one of Oracle's first customers was
the CIA...
Oracle database is a commercial, relational database management system from Oracle
Corporation.
Oracle Database, the relational database management system from Oracle Corporation,
is arguably the most powerful and feature rich database on the market.
Oracle Corporation was founded in 1977 in Redwood, California. They introduced the
first Relational Database Management System based on the IBM System/R model and
the first database management system utilizing IBM's Structured Query Language (SQL)
technology.
Today, the Oracle DBMS is supported on over 80 different operating environments,
ranging from IBM mainframes, DEC VAX minicomputers, UNIX-based minicomputers,
Windows NT and several proprietary hardware-operating system platforms, and is
clearly the world's largest RDBMS vendor.

By Subhash Reddy Aedla Page 32 of 304


ORACLE

Oracle employs more than 42,000 professionals in 93 countries around the world. Their
expenditure for research and development is approximately 13% of their revenues.
Larry Ellison founded Software Development Laboratories in 1977. In 1979 SDL changed
its company name to Relational Software, Inc. (RSI) and introduced its product Oracle V2
as an early commercially-available relational database system. The version did not
support transactions, but implemented the basic SQL functionality of queries and joins.
There was no version 1, instead the first version was called version 2 as a marketing
strategy.
In 1983, RSI was renamed Oracle Corporation to more closely align itself with its flagship
product. Oracle version 3 was released which had been re-written in the C Programming
Language and supported commit and rollback transaction functionalities. Platform
support was extended to UNIX with this version, which until then had run on Digital
VAX/VMS systems.
Lawrence Joseph (Larry) Ellison (Born: 1944, Chicago) is president and CEO of Oracle
Corporation. He's the Oracle worlds hero, and he should be. Oracle Corporation, the
company he founded with Robert N. (Bob) Miner and Edward A. (Ed) Oates back in
1977, has emerged as the world's largest vendor of software that helps large
corporations and governments better manage their information.
Bruce Scott was one of the first employees at Oracle (then Software Development
Laboratories). He co-founded Gupta Technology (now known as Centura Software) in
1984 with Umang Gupta, and later became CEO and founder of PointBase, Inc.
Bruce was co-author and co-architect of Oracle V1, V2 and V3. The SCOTT schema (EMP
and DEPT tables), with password TIGER, was created by him. Tiger was the name of his
cat.
On June 16, 1903, Ford Motor Company was incorporated and the Industrial Revolution
started to hit a major acceleration point. On June 16, 1977, a similar event occurred
with the incorporation of Oracle Corporation (then called Systems Development
Laboratories -- SDL).

Oracle celebrates 30 years


Oracle celebrated its 30th anniversary on June 16, 2007, as a multi-billion-dollar
company literally supporting every major business. It's amazing to look back on the
history of Oracle Corporation and the diverse team that has led to its success. Larry has
been the driving factor of Oracle the company, but Bob Miner, whose Assyrian family
emigrated from Ada, Iran, was the driving factor of Oracle the product.

By Subhash Reddy Aedla Page 33 of 304


ORACLE

America is all about freedom, resilience and opportunity. Larry Ellison and Bob Miner
are examples of what is possible in a free society. Larry's surname is even based on Ellis
Island. Larry's entrepreneurial success story shows that anything is possible where
people enjoy freedom and an entrepreneur spirit burns. On the Statue of Liberty it
reads: "Give me your tired, your poor, your huddled masses yearning to breathe free, the
wretched refuse of your teeming shore. Send these, the homeless, tempest-tost to me, I
lift my lamp beside the golden door!" That golden door eventually led Larry to the
Golden Gate Bridge and the establishment of Oracle Corporation in Silicon Valley in
1977.
The early years at Oracle through the eyes of Bruce Scott
Prior to forming Oracle, Bob Miner was Larry Ellison's manager where they worked at
Ampex together on a CIA project code-named "Oracle." Larry chose Bob as his manager
because he liked Bob a lot more than his original manager. Ed Oates, another founder of
Oracle, happened to be walking by Bob Miner's door when Larry Ellison mentioned his
(Larry's) wife's name. It turned out to be Ed Oates' lab partner from high school. Bruce
Scott, who would be hired upon the formation of the company, is the "Scott" in
scott/tiger (Tiger was Bruce's daughter's cat).
When Larry went on to work at Precision Instruments, he discovered Precision
Instruments had a need to do a $400,000 consulting project. For three or four
engineers, that was a lot of money back then, since wages were about one-tenth what
they are now. Larry landed the deal. Larry was not part of the new company when it was
founded; he was still at Precision Instruments. The new company was called Software
Development Labs (SDL). It had three employees when he started the company in
August of 1977. Bob Miner was the president; Ed Oates and Larry were both software
engineers. They did 90% of the work on this two-year project in the first year, so they
had the next year to work on Oracle. Ed Oates finished the other 10% of the project over
the next year while Bob Miner and Larry started to write the Oracle database.
When they completed the Precision Instruments work, they had about $200,000 in the
bank. They decided and wanted to be a product company and not a consulting
company. Bob wanted to build an ISAM product for the PDP11. He felt there was a need
for an access layer. Larry wasn't interested in that at all. Larry had been following what
IBM was doing and he found a paper on the System/R based on Codd's 1970 paper on
relational databases. It described the SQL language, which was at the time called
SEQUEL/2.

Oracle RDBMS history over the years

By Subhash Reddy Aedla Page 34 of 304


ORACLE

1970 -- Dr. Edgar Codd publishes his theory of relational data modeling.
1977 -- Software Development Laboratories (SDL) formed by Larry Ellison, Bob Miner, Ed
Oates and Bruce Scott with $2,000 of startup cash. Larry and Bob come from Ampex
where they were working on a CIA project code-named "Oracle." Bob and Bruce begin
work on the database.
1978 -- The CIA is the first customer, yet the product is not released commercially as of
yet. SDL changes its name to Relational Software Inc. (RSI).
1979 -- RSI ships the first commercial version, Version 2 (there is no V1 shipped on fears
that people won't buy a first version of software) of the database written in Assembler
Language. The first commercial version of the software is sold to Wright-Patterson Air
Force Base. It is the first commercial RDBMS on the market.
1981 -- The first tool, Interactive Application Facility (IAF), which is a predecessor to
Oracle's future SQL*Forms tool, is created.
1982 -- RSI changes its name to Oracle Systems Corporation (OSC) and then simplifies
the name to Oracle Corporation.
1983 -- Version 3, written in C (which makes it portable) is shipped. Bob Miner writes
half, while also supporting the Assembler-based V2, and Bruce Scott writes the other
half. It is the first 32-bit RDBMS.
1984 -- Version 4 released. First tools released, (IAG-genform, IAG-runform, RPT). First
database with read consistency. Oracle ported to the PC.
1985 -- Version 5 and 5.1 are released. First Parallel Server database on VMS/VAX.
1986 -- Oracle goes public March 12 (the day before Microsoft and eight days after Sun).
The stock opens at $15 and closes at $20.75. Oracle Client/Server is introduced; first
client/server database. Oracle5.1 is released.
1987 -- Oracle is the largest DBMS company. Oracle Applications group started. First
SMP (symmetrical multi-processing) database introduced.
1987 -- Oracle's Rich Niemiec along with Brad Brown and Joe Trezzo working at Oracle
(now at TUSC) implement the first production client/server application running Oracle
on a souped-up 286 running 16 concurrent client/server users for NEC Corporation.
1988 -- Oracle V6 released. First row-level locking. First hot database backup. Oracle
moves from Belmont to Redwood Shores. PL/SQL introduced.
1992 -- Oracle V7 is released.

By Subhash Reddy Aedla Page 35 of 304


ORACLE

1993 -- Oracle GUI client/server development tools introduced. Oracle Applications


moved from character mode to client/server.
1994 -- Bob Miner, the genius behind the Oracle database technology, dies of cancer.
1995 -- First 64-bit database.
1996 -- Oracle7.3 released.
1997 -- Oracle8 is introduced. Oracle Application Server is introduced. Applications for
the Web introduced. Oracle is the first Web database. Oracle BI tools like Discoverer are
introduced for data warehousing. Tools have native Java support.
1998 -- First major RDBMS (Oracle8) ported to Linux. Applications 11 shipped. Oracle is
the first database with XML support.
1999 -- Oracle8i released. Integrates Java/XML into development tools. Oracle is the
first database with native Java support.
2000 -- Oracle9i Application Server released; it becomes the first database with middle-
tier cache. Launches E-Business Suite, wireless database with OracleMobile, Oracle9i
Application Server Wireless and Internet File System (iFS).
2001 -- Oracle9i (9.1) released. Oracle is the first database with Real Application Clusters
(RAC).
2002 -- Oracle9i Release 2 (9.2) released.
2003 -- Oracle at France Telecom is No. 1 on Winter Group's Top 10 in DB size at 29TB.
2003 -- Oracle10g comes out -- Grid-focused, Encrypted Backups, Auto-Tuning and ASM.
2005 -- Oracle RAC at Amazon hits the Winter Group's Top 10 in DB size at 25TB.
2005 -- Oracle buys PeopleSoft (includes JD Edwards), Oblix (Identity Management),
Retek (Retail) $630M, TimesTen (in-memory DB) and Innobase (InnoDB Open Source).
2006 -- Oracle buys Siebel for $5.8B, Sleepycat Software (Open Source) and Stellant
(Content Management). Oracle with an Open Source push offers "unbreakable" support
for Red Hat Linux.
2006 -- Oracle10g Release2 comes out in fall.
2007 -- Oracle buys Hyperion for $3.3B.
2007 -- Oracle 11g comes out.
when asked Bruce Scott what made Oracle successful in his mind. Bruce said: "I've
thought about this a lot. I really think that it was Larry. There were a lot of other
databases (like Ingres) out there that we beat. It was really Larry's charisma, vision and

By Subhash Reddy Aedla Page 36 of 304


ORACLE

his determination to make this thing work no matter what. It's just the way Larry thinks.
I can give you an example I tell people that exemplifies his thought process: We had
space allocated to us and we needed to get our terminals strung to the computer room
next door. We didn't have anywhere to really string the wiring. Larry picks up a hammer,
crashes a hole in the middle of the wall and says there you go. It's just the way he
thinks, make a hole, make it happen somehow. It was Larry, the right thing and the right
time."

What new features were introduced in Oracle versions


Oracle 10g Release 2 (10.2.0) - September 2005
 Transparent Data Encryption
 Async commits
 CONNECT ROLE can not only connect
 Passwords for DB Links are encypted
 New asmcmd utility for maanging ASM storage

Oracle 10g Release 1 (10.1.0)


 Automatic Storage Management (ASM)
 Automatic Workload Repository (AWR)
 Automatic Database Diagnostics Monitor (ADDM)
 DBMS_FILE_TRANSFER Package
 New job scheduler DBMS_SCHEDULER
 Data Pump - replacement for the EXP and IMP utilities

Oracle 9i Release 2 (9.2.0)


 Oracle Streams (for data movement - can potentially replace Oracle Advance
Replication and Standby Databases).
 XML DB (Oracle is now a standards compliant XML database)
 Data segment compression (compress keys in tables - only when loading data)
 Cluster file system for Windows and Linux (raw devices are no longer required).
 Create logical standby databases with Data Guard
 Java 1.3 used inside the database

Oracle 9i Release 1 (9.0.1) - June 2001


 Traditional rollback segments (RBS) are still available, but can be replaced with
automated System Managed Undo (SMU). Using SMU, Oracle will create it's own
"Rollback Segments" and size them automatically without any DBA involvement.
 Flashback query (dbms_flashback.enable) - one can query data as it looked at
some point in the past. This feature will allow users to correct wrongly
committed transactions without contacting the DBA to do a database restore.

By Subhash Reddy Aedla Page 37 of 304


ORACLE

 Use Oracle Ultra Search for searching databases, file systems, etc. The
UltraSearch crawler fetch data and hand it to Oracle Text to be indexed.
 Oracle Nameserver is still available, but deprecate in favor of LDAP Naming
(using the Oracle Internet Directory Server). A nameserver proxy is provided for
backwards compatibility as pre-8i client cannot resolve names from an LDAP
server.
 Oracle Parallel Server's (OPS) scalebility was improved - now called Real
Application Clusters (RAC). Full Cache Fusion implemented. Any application can
scale in a database cluster. Applications doesn't need to be cluster aware
anymore.
 The Oracle Standby DB feature renamed to Oracle Data Guard. New Logical
Standby databases replay SQL on standby site allowing the database to be used
for normal read write operations. The Data Guard Broker allows single step fail-
over when disaster strikes.
 Scrolling cursor support. Oracle9i allows fetching backwards in a result set.
 Dynamic Memory Management - Buffer Pools and shared pool can be resized
on-the-fly. This eliminates the need to restart the database each time parameter
changes were made.
 On-line table and index reorganization.
 VI (Virtual Interface) protocol support, an alternative to TCP/IP, available for use
with Oracle Net (SQL*Net). VI provides fast communications between
components in a cluster.
 Build in XML Developers Kit (XDK). New data types for XML (XMLType), URI's, etc.
XML integrated with AQ.
 Cost Based Optimizer now also consider memory and CPU, not only disk access
cost as before.
 PL/SQL programs can be natively compiled to binaries.
 Deep data protection - fine grained security and auditing. Put security on DB
level. SQL access do not mean unrestricted access.
 Resumable backups and statements - suspend statement instead of rolling back
immediately.
 List Partitioning - partitioning on a list of values.
 ETL (eXtract, transformation, load) Operations - with external tables and
pipelining.
 OLAP - Express functionality included in the DB.
 Data Mining - Oracle Darwin's features included in the DB.
Oracle 8i (8.1.7)
 Static HTTP server included (Apache)

By Subhash Reddy Aedla Page 38 of 304


ORACLE

 JVM Accelerator to improve performance of Java code


 Java Server Pages (JSP) engine
 MemStat - A new utility for analyzing Java Memory footprints
 OIS - Oracle Intergration Server introduced.
 PLSQL Gateway introduced for deploying PL/SQL based solutions on the Web
 Enterprise Manager Enhancements - including new HTML based reporting and
Advanced Replication functionality included.
 New Database Character Ser Migration utilility included.
Oracle 8i (8.1.6)
 PL/SQL Server Pages (PSP's)
 DBA Studio Introduced
 Statspack
 New SQL Functions (rank, moving average)
 ALTER FREELISTS command (previously done by DROP/CREATE TABLE)
 Checksums always on for SYSTEM tablespace allowing many possible corruptions
to be fixed before writing to disk
 XML Parser for Java
 New PLSQL encrypt/decrypt package introduced
 User and Schemas sepapated
 Numerous Performance Enhancements

Oracle 8i (8.1.5)
 Fast Start recovery - Checkpoint rate auto-adjusted to meet roll forward criteria
 Reorganize indexes/index only tables which users accessing data - Online index
rebuilds
 Log Miner introduced - Allows on-line or archived redo logs to be viewed via SQL
 OPS Cache Fusion introduced avoiding disk I/O during cross-node
communication
 Advanced Queueing improvements (security, performance, OO4O support
 User Security Improvements - more centralisation, single enterprise user,
users/roles across multiple databases.
 Virtual private database
 JAVA stored procedures (Oracle Java VM)
 Oracle iFS
 Resource Management using proirities - resource classes
 Hash and Composite partitioned table types
 SQL*Loader direct load API

By Subhash Reddy Aedla Page 39 of 304


ORACLE

 Copy optimizer statistics across databases to ensure same access paths across
different environments.
 Stanby Database - Auto shipping and application of redo logs. Read Only queries
on standby database allowed.
 Enterprise Manager v2 delivered
 NLS - Euro Symbol supported
 Analyze tables in parallel
 Temporary tables supported.
 Net8 support for SSL, HTTP, HOP protocols
 Transportable tablespaces between databases
 Locally managed tablespaces - automatic sizing of extents, elimination of
tablespace fragmentation, tablespace information managed in tablespace (i.e
noved from data dictionary) improving tablespace reliability
 Drop Column on table (Finally !!!!!)
 DBMS_DEBUG PL/SQL package, DBMS_SQL replaced by new EXECUTE
IMMEDIATE statement
 Progress Monitor to track long running DML,DDL
 Functional Indexes - NLS, case insensitive, descending
Oracle 8.0 - June 1997
 Object Relational database
 Object Types (not just date, character, number as in v7
 SQL3 standard
 Call external procedures
 LOB >1 per table
 Partitioned Tables and Indexes
 export/import individual partitions
 partitions in multiple tablespaces
 online/offline, backup/recover individual partitions
 merge/balance partitions
 Advanced Queuing for message handling
 Many performance improvements to SQL/PLSQL/OCI making more efficient use
of CPU/Memory. V7 limits extended (e.g. 1000 columns/table, 4000 bytes
VARCHAR2)
 Parallel DML statements
 Connection Pooling ( uses the physical connection for idle users and
transparently re-establishes the connection when needed ) to support more
concurrent users.
 Improved "STAR" Query optimizer

By Subhash Reddy Aedla Page 40 of 304


ORACLE

 Integrated Distributed Lock Manager in Oracle PS (as opposed to Operating


system DLM in v7).
 Performance improvements in OPS - global V$ views introduced across all
instances, transparent failover to a new node
 Data Cartridges introduced on database (e.g. image, video, context, time, spatial)
 Backup/Recovery improvements - Tablespace point in time recovery,
incremental backups, parallel backup/recovery. Recovery manager introduced
 Security Server introduced for central user administration. User password expiry,
password profiles, allow custom password scheme. Privileged database links (no
need for password to be stored)
 Fast Refresh for complex snapshots, parallel replication, PL/SQL replication code
moved in to Oracle kernel. Replication manager introduced.
 Index Organized tables
 Deferred integrity constraint checking (deferred until end of transaction instead
of end of statement).
 SQL*Net replaced by Net8
 Reverse Key indexes
 Any VIEW updateable
 New ROWID format
Oracle 7.3
 Partitioned Views
 Bitmapped Indexes
 Asynchronous read ahead for table scans
 Standby Database
 Deferred transaction recovery on instance startup
 Updatable Join Views (with restrictions)
 SQLDBA no longer shipped.
 Index rebuilds
 db_verify introduced
 Context Option
 Spatial Data Option
 Tablespaces changes - Coalesce, Temporary Permanent,
 Trigger compilation, debug
 Unlimited extents on STORAGE clause.
 Some init.ora parameters modifiable - TIMED_STATISTICS
 HASH Joins, Antijoins
 Histograms
 Dependencies

By Subhash Reddy Aedla Page 41 of 304


ORACLE

 Oracle Trace
 Advanced Replication Object Groups
 PL/SQL - UTL_FILE
Oracle 7.2
 Resizable, autoextend data files
 Shrink Rollback Segments manually
 Create table, index UNRECOVERABLE
 Subquery in FROM clause
 PL/SQL wrapper
 PL/SQL Cursor variables
 Checksums - DB_BLOCK_CHECKSUM, LOG_BLOCK_CHECKSUM
 Parallel create table
 Job Queues - DBMS_JOB
 DBMS_SPACE
 DBMS Application Info
 Sorting Improvements - SORT_DIRECT_WRITES

Oracle 7.1
 ANSI/ISO SQL92 Entry Level
 Advanced Replication - Symmetric Data replication
 Snapshot Refresh Groups
 Parallel Recovery
 Dynamic SQL - DBMS_SQL
 Parallel Query Options - query, index creation, data loading
 Server Manager introduced
 Read Only tablespaces

Oracle 7.0 - June 1992


 Database Integrity Constraints (primary, foreign keys, check constraints, default
values)
 Stored procedures and functions, procedure packages
 Database Triggers
 View compilation
 User defined SQL functions
 Role based security
 Multiple Redo members - mirrored online redo log files
 Resource Limits - Profiles
 Much enhanced Auditing
 Enhanced Distributed database functionality - INSERTS, UPDATES,DELETES, 2PC

By Subhash Reddy Aedla Page 42 of 304


ORACLE

 Incomplete database recovery (e.g SCN)


 Cost based optimiser
 TRUNCATE tables
 Datatype changes (i.e VARCHAR2 CHAR, VARCHAR)
 SQL*Net v2, MTS
 Checkpoint process
 Data replication - Snapshots
Oracle 6 - July 1988
 Row-level locking
 On-line backups
 PL/SQL in the database

Oracle 5.1
 Distributed queries

Oracle 5.0 - 1986


 Supporting for the Client-Server model (distributed processing)

Oracle 4 - 1984
 Read consistency

Oracle 3 - 1981
 Supports COMMIT and ROLLBACK of transactions
 Re-written in the C Programming Language

Oracle 2 - 1979
 First public release
 basic SQL functionality of queries and joins

Difference between the Enterprise, Standard and Personal Editions of Oracle


Oracle Enterprise Edition:
Enterprise Edition is the full (top of the range) version or the Oracle Database Server.
Options like RAC, Partitioning, Spatial, etc. can be purchased separately to enhance the
functionality of the database.
Oracle Standard Edition:
Standard Edition is designed for smaller businesses and enterprises. It offers a subset of
the features/ functionality implemented in Enterprise Edition. Database options like
Data Guard, Partitioning, Spatial, etc. is not available with Standard Edition (from 10g
one can use RAC with Standard Edition). Standard Edition can only be licensed on
servers with a maximum capacity of four processors.

By Subhash Reddy Aedla Page 43 of 304


ORACLE

Oracle Standard Edition One:


Standard Edition One is a low cost, entry-level version of the Oracle Standard Edition
database server. Standard Edition One can only be licensed on small servers with a
maximum capacity of two processors.
Oracle Personal Edition:
Personal Oracle is a single user version of the database server. It is mostly the same as
Enterprise Edition, but doesn't support advanced options like RAC, Streams, XMLDB, etc.
Oracle Lite:
Oracle Light is a database engine that can be used on mobile platforms like cell phones
and PDA's.
Oracle XE:
Express Edition (XE) is a free, downloadable version of the Oracle database server.
Oracle XE can only be used on single processor machines. It can only manage up to 4 GB
of data and 1 GB of memory. ISVs can embed XE in 3rd party products and redistribute it
freely.

By Subhash Reddy Aedla Page 44 of 304


ORACLE

Working with Oracle


Oracle is an Object Relational Database Management System (ORDBMS). It offers the
capabilities of both relational and object-oriented database systems. In general, objects
can be defined as reusable software codes which are location independent and perform
a specific task on any application environment with little or no change to code.
Oracle products are based on a concept known as the client/server technology. This
concept involves segregating the process of an application between two systems. One
performs all activities related to the database (Server) and the other performs activities
that help the user to interact with the application (Client).
A client or front end database application also interacts with the database by requesting
and receiving information from the ‘database server’. It acts as interface between the
user and the database. Further, it also checks for validation against the data entered by
the user.
The commonly used front end tools of Oracle are
 SQL * Plus
 Oracle Forms
 Reports
 Visual Basics
These tools provided by Oracle are so user friendly that a person with minimum skills in
the field of computers can access them with ease.

SQL {Structured Query Language}


SQL is a database access, nonprocedural language. Users describe in SQL what they
want done, and the SQL language compiler automatically generates a procedure to
navigate the database and perform the desired task.
IBM Research developed and defined SQL, and ANSI/ISO has refined SQL as the standard
language for relational database management systems. The minimal conformance level
for SQL-99 is known as Core. Core SQL-99 is a superset of SQL-92 Entry Level
specification. Oracle9i is broadly compatible with the SQL-99 Core specification.
Oracle SQL includes many extensions to the ANSI/ISO standard SQL language, and
Oracle tools and applications provide additional statements. The Oracle tools SQL*Plus
and Oracle Enterprise Manager let you run any ANSI/ISO standard SQL statement
against an Oracle database, as well as additional statements or functions that are
available for those tools.

By Subhash Reddy Aedla Page 45 of 304


ORACLE

Oracle SQLJ lets applications programmers embed static SQL operations in Java code in
a way that is compatible with the Java design philosophy. A SQLJ program is a Java
program containing embedded static SQL statements that comply with the ANSI-
standard SQLJ Language Reference syntax.
Although some Oracle tools and applications simplify or mask SQL use, all database
operations are performed using SQL. Any other data access method circumvents the
security built into Oracle and potentially compromise data security and integrity.
Oracle was the first company to release a product that used English based structure
query language. This language allowed end users to extract information themselves,
without using a systems group for every little report
Oracle’s language has structure, just as English or any other language has structure. It
has rules of grammar and syntax, but they are basically the normal rules of careful
English speech and can be readily understood.
SQL was invented and developed by IBM in early 1970,s IBM was able to demonstrate
how to control relational database using SQL. This ANSI standardized SQL was
implemented by Oracle Corporation thoroughly 100%. Oracle database language SQL,
which is used for storing and retrieving information in Oracle. A table is a primary
database object of SQL that is used to store data. A table holds data in the form of rows
and columns.
In order to communicate with the database SQL supports the following categories of
commands.
1. Data Definition Language
(create, alter, drop commands)
2. Data Manipulation Language
(insert, select, delete and up date commands )
3. Transaction Control Language
(commit, savepoint, and rollback command)
4. Data Control Language
(grant and revoke commands )
Advantages of SQL:
1. Non-procedural language, because more than are record can be accessed rather
than one record at a time
2. It is the common language for all relational databases. In other words it is
portable and it requires very few modifications so that it can work on other
databases.

By Subhash Reddy Aedla Page 46 of 304


ORACLE

3. Very simple commands for querying, inserting, deleting, and modifying data and
objects.
SQL*Plus (User Friendly Interface): It is a powerful Oracle product that can take your
instructions from Oracle, check them for correctness, submit them to Oracle, and then
modify or reformat the response Oracle gives back, based on the order or directions
that you have set in place.
It may be little confusing at first to understand the difference between what SQL*Plus is
doing and Oracle is doing, especially since the error messages that Oracle produces are
simply passed onto you by SQL*Plus. In SQL*Plus case is irrelevant.
With Oracle 6, a new tool called SQL*DBA was introduces which overtook many of the
database responsibilities, such as backup and recovery, startup and shutdown.
Oracle 7, 8, 9 provide a new interface called Enterprise Manager to replace SQL*DBA as
a database management tool.
Through SQL*PLUS we can store, retrieve, edit, enter and run SQL commands and
PL/SQL blocks. Using SQL*Plus we can perform calculations, list column definitions for
any table and can also format query results in the form of a report.
SQL*Plus is most commonly used for simple queries and print reports. Getting SQL*Plus
to format information in reports according to your needs requires, only a handful of
commands or keywords that interact SQL*Plus how to behave.
SQL*Plus also has a tiny, built in editor of its own, some times called as command line
editor, which will allow you to quickly modify a SQL query without leaving SQL*Plus.
Commands and its Description of SQL*Plus
Remark: Tells SQL*Plus that the words to follow are to be treated as comments, note
restrictions.
Set headsep: The heading separator identifies the single character that tells SQL*Plus to
split a little one, two or more lines.
Title: Sets the top title for each page of a report.
Btitle: Sets the bottom title for each page of a report.
Column: Gives SQL*Plus a variety of instructions on the heading, format, and treatment
of a column.
Break on: Tells SQL*Plus where to put spaces between sections of a report, or where to
break for subtotals and totals.
Compute sum: Makes PL/SQL calculates subtotal.

By Subhash Reddy Aedla Page 47 of 304


ORACLE

Set pagesize: Sets the maximum number of lines per page.


Set newpage: Sets the number of blank lines between pages.
Set linesize: sets the maximum number of characters allowed on any line of the report.
Set SQLprompt: Sets the prompt of QL in your required fashion.
Spool: Moves a report you would normally see displayed on the screen into a file, so you
can print it.

/**/: Marks the beginning and ending of a comment within SQL entry. This command is
similar to Remark.

--: Marks the beginning of an inline comment within a SQL entry. Treats every thing
from the mark to the end of the line as a comment. This command is similar to Remark.
Set pause: Makes the screen display stop between pages of display.
Save: Saves the SQL queries you are creating into the file of you own choice.
Host: Sends any command to the host operation system.
Start: Tells SQL*Plus to follow (Execute) the instructions you have saved in a file.
Edit: Pops you art of SQL*Plus and into an editor of your choice.
Examples
1. Rem name: activity-sql type: start file report
2. Set headsep:
3. Title: ‘sales by product during 2001’
4. B title ‘by G. B. Talbolt’
5. Column item heading ‘what was sold’
Column item format a18
Column item truncated
Column rate format 90.99
Column ext format 990.99
Break on item skip 2
6. Compute sum on item
7. Set line size 79
8. Set page size 24

By Subhash Reddy Aedla Page 48 of 304


ORACLE

9. Set new page 0


10. Spool activity 1st
Query
Spool off
11. Set pause ‘more….’
Set pause on
Set pause off
12. Save fred . sql
13. Store set my-settings sql create :- save or correct sql plus environment
14. Define-editor =”vi”
15. Hoot vi fread.sql
16. Start fred.sql

SQL Vs SQL*PLUS
SQL is a standard structured query language common to all relational databases. SQL is
database language used for storing and retrieving data from the database. Most
Relational Database management systems provide extensions to SQL to make it easy for
application developers. SQL*PLUS is an Oracle specific program which accepts SQL
commands and PL/SQL blocks and executes them. SQL*PLUS enables manipulation of
SQL commands and PL/SQL Blocks. It also performs many additional tasks such as
1. Enter, edit, store, retrieve, and run SQL commands and PL/SQL blocks.
2. Format, perform calculations, store, and print query results in the form of
reports.
3. List column definitions for any table
4. Access and copy data between SQL databases
5. Send messages to and accept responses from an end user
Advantages of Oracle 9i for choosing it as the RDBMS for effectively managing data:
1. Ability to retrieve data spread across multiple tables.
2. Oracle specific SQL*PLUS functions used when required to query the database
especially to decide future course of action.

By Subhash Reddy Aedla Page 49 of 304


ORACLE

3. Provisions to maintain integrity of the database to avoid duplication and have


constant checks on the validity of data
4. Ability to break the most frequently used object, the table into smaller units
there by reducing the risk of loss of data.
5. With a number of clients accessing the database, Oracle 9i allows explicit locking
of data, concurrent access of data for manipulation can be prevented in this way.
6. Storing of information out-of-line with the table is also a major advantage. This
allows unstructured information to be stored is a different location present in
the table. LOB data types support this concept.
7. Oracle 9i also supports OOP’s concepts, making it a powerful object oriented
database.
Oracle SQL statements are divided into the following categories:
 Data Manipulation Language Statements
 Data Definition Language Statements
 Transaction Control Statements
 Session Control Statements
 System Control Statements
 Embedded SQL Statements

Data Manipulation Language Statements


Data manipulation language (DML) statements query or manipulate data in existing
schema objects. They enable you to:
 Retrieve data from one or more tables or views (SELECT); fetches can be Add new
rows of data into a table or view (INSERT)
 Change column values in existing rows of a table or view (UPDATE)
 Update or insert rows conditionally into a table or view (MERGE)
 Remove rows from tables or views (DELETE)
 See the execution plan for a SQL statement (EXPLAIN PLAN)
 Lock a table or view, temporarily limiting other users' access (LOCK TABLE)
DML statements are the most frequently used SQL statements. Some examples of DML
statements are:

By Subhash Reddy Aedla Page 50 of 304


ORACLE

SELECT last_name, manager_id, commission_pct + salary FROM employees;


INSERT INTO employees VALUES
(1234, 'DAVIS', 'SALESMAN', 7698, '14-FEB-1988', 1600, 500, 30);
DELETE FROM employees WHERE last_name IN ('WARD','JONES');

Data Definition Language Statements


Data definition language (DDL) statements define, alter the structure of, and drop
schema objects. DDL statements enable you to:
 Create, alter, and drop schema objects and other database structures, including
the database itself and database users (CREATE, ALTER, DROP)
 Change the names of schema objects (RENAME)
 Delete all the data in schema objects without removing the objects' structure
(TRUNCATE)
 Grant and revoke privileges and roles (GRANT, REVOKE)
 Turn auditing options on and off (AUDIT, NOAUDIT)
 Add a comment to the data dictionary (COMMENT)
DDL statements implicitly commit the preceding and start a new transaction. Some
examples of DDL statements are:
CREATE TABLE plants
(COMMON_NAME VARCHAR2 (15), LATIN_NAME VARCHAR2 (40));
DROP TABLE plants;
GRANT SELECT ON employees TO scott;
REVOKE DELETE ON employees FROM scott;

Transaction Control Statements


Transaction control statements manage the changes made by DML statements and
group DML statements into transactions. They enable you to:
 Make a transaction's changes permanent (COMMIT)
 Undo the changes in a transaction, either since the transaction started or since a
savepoint (ROLLBACK)
 Set a point to which you can roll back (SAVEPOINT)
 Establish properties for a transaction ( SET TRANSACTION)

By Subhash Reddy Aedla Page 51 of 304


ORACLE

Session Control Statements


Session control statements manage the properties of a particular user's session. For
example, they enable you to:
 Alter the current session by performing a specialized function, such as enabling
and disabling the SQL trace facility (ALTER SESSION)
 Enable and disable roles (groups of privileges) for the current session (SET ROLE)

System Control Statements


System control statements change the properties of the Oracle server instance. The only
system control statement is ALTER SYSTEM. It enables you to change settings (such as the
minimum number of shared servers), kill a session, and perform other tasks.

Embedded SQL Statements


Embedded SQL statements incorporate DDL, DML, and transaction control statements
within a procedural language program. They are used with the Oracle precompilers.
Embedded SQL statements enable you to:
 Define, allocate, and release cursors (DECLARE CURSOR, OPEN, CLOSE)
 Specify a database and connect to Oracle (DECLARE DATABASE, CONNECT)
 Assign variable names (DECLARE STATEMENT)
 Initialize descriptors (DESCRIBE)
 Specify how error and warning conditions are handled (WHENEVER)
 Parse and run SQL statements (PREPARE, EXECUTE, EXECUTE IMMEDIATE)
 Retrieve data from the database (FETCH)
Identification of Nonstandard SQL
Oracle provides extensions to the standard SQL database language with integrity
enhancement. The Federal Information Processing Standard for SQL (FIPS 127-2)
requires vendors to supply a method for identifying SQL statements that use such
extensions. You can identify or flag Oracle extensions in interactive SQL, the Oracle
precompilers, or SQL*Module by using the FIPS flagger.
If you are concerned with the portability of your applications to other implementations
of SQL, use the FIPS flagger.

By Subhash Reddy Aedla Page 52 of 304


ORACLE

Recursive SQL
When a DDL statement is issued, Oracle implicitly issues recursive SQL statements that
modify data dictionary information. Users need not be concerned with the recursive SQL
internally performed by Oracle.

The Physical Oracle Architecture


All buildings, from the home you live in to the place you work, have an architecture that
keeps the building together. This architecture (if it’s well designed), will keep the
building from falling apart, keep you nice and warm, and provide you with easy access
to facilities like water fountains and restrooms.
A well-crafted architecture will also help you work more efficiently. The same is true for
databases. Despite the name “Oracle”, there is no magic!
The architecture that Oracle has built its database around is designed to perform
quickly, efficiently and without errors.
In this section we will introduce you to the Oracle architecture. This architecture
includes the following components:
* The System Global Area (SGA) and other memory areas that utilize RAM
* Database related background processes
* Tablespaces and Datafiles
* Database related files
* The instance and the database
Next we will look at each of these components in more detail. Finally we put the
components together into a single “big picture” view, and see how all these pieces fit
together to complete the Oracle puzzle. Keep in mind that the discussion in this chapter
is limited to the overall database architecture. In later chapters we will get into the finer
details of managing these structures.
With this in mind, let’s drill down a bit deeper into the architecture of Oracle and learn
more about memory structures, the part of Oracle that utilizes your system’s RAM.
Diving into the RAM Pools
All computers have memory. Memory should not be confused with disk storage.
Memory is volatile, which means its content is lost after the power is removed. Memory
is also very fast. RAM memory is expressed in nanoseconds (billionths of a second) and
disk speed is in milliseconds (thousandths of a second). In Oracle, RAM speed is

By Subhash Reddy Aedla Page 53 of 304


ORACLE

hundreds of times faster than disks. Don’t get burned by tiny pools. See the Google
search ”oracle cache disk speed” for details.
Disk storage is non-volatile. This means that the data stored on a disk will remain after
the power is turned off. Disks are always slower than RAM, but disks are hundreds of
times cheaper than RAM.
There is a trade-off between memory and disks: Memory is fast but expensive (about
$1,000 per gigabyte), whereas disks are slower but very cheap. Thus, memory is used for
short-term storage of information that is frequently needed and disks are used for long-
term storage of information.
Oracle has a number of memory areas that it uses to store information. In this section
we will address the main Oracle memory areas. They are called:
* The System Global Area (SGA) – RAM areas for the Oracle programs.
* The Program Global Area (PGA) – Private RAM areas for individual client connections
to Oracle

The Instance and the Database


We are almost at the end of our introduction to the Oracle database architecture. We
can’t complete this journey, however, until we define two more terms, instance and
database. The Oracle instance is the combination of the Oracle SGA and the related
background processes (the programs, PMON, SMON, etc.). When the SGA RAM memory
is successfully allocated and the Oracle database processes are running normally, the
instance is said to be “up”.
However, and instance is sometimes different from a database. You can have the
instance running, but the database might not be mounted or open. The Oracle Database
includes the physical files we have discussed: the datafiles, the control file, and the redo
log files. When the Oracle instance is running, it can attach itself to a database,
“mount” the control file, and finally “open” the datafiles and redo log files. This is an
important distinction because many Oracle operations must be done with the instance
started but the database is not open.

Oracle Architecture Concepts


In the previous section we discussed the Oracle physical architecture. Things like files,
programs and hardware are all considered physical pieces (or physical properties) of the
Oracle database. In this section we are concerned with the logical pieces of the Oracle
database.

By Subhash Reddy Aedla Page 54 of 304


ORACLE

Oracle segregates “physical components” (the .dbf files on disk) my mapping them into
“logical” containers called tablespaces. In turn, we allocate our tables and indexes
inside these tablespace, and Oracle takes-care of the interface to the physical disk files.
In this section we will look at the following logical database elements.
* Tablespaces (not completely a logical thing actually!)
* Blocks
* Extents
* Segments
We will then give you a big-picture summary of the relationships between these logical
objects. Note that this section just provides you with some basic concepts. We will get
into much more detail in the chapters to come!

Oracle SGA Concepts


The System Global Area (SGA) is a group of shared memory areas that are dedicated to
an Oracle “instance” (an instance is your database programs and RAM).
All Oracle processes use the SGA to hold information. The SGA is used to store incoming
data (the data buffers as defined by the db_cache_size parameter), and internal control
information that is needed by the database. You control the amount of memory to be
allocated to the SGA by setting some of the Oracle “initialization parameters”. These
might include db_cache_size, shared_pool_size and log_buffer.
In Oracle Database 10g you only need to define two parameters (sga_target and
sga_max_size) to configure your SGA. If these parameters are configured, Oracle will
calculate how much memory to allocate to the different areas of the SGA using a feature
called Automatic Memory Management (AMM). As you gain experience you may want
to manually allocate memory to each individual area of the SGA with the initialization
parameters.
We have already noted that the SGA was sub-divided into several memory structures
that each have different missions. The main areas contained in the SGA that you will be
initially interested in have complicated names, but are actually quite simple:
* The buffer cache (db_cache_size)
* The shared pool (shared_pool_size)
* The redo log buffer (log_buffer)
Let’s look at these memory areas in more detail.

By Subhash Reddy Aedla Page 55 of 304


ORACLE

Inside the Data Buffer Cache


The Buffer Cache (also called the database buffer cache) is where Oracle stores data
blocks. With a few exceptions, any data coming in or going out of the database will pass
through the buffer cache.
The total space in the Database Buffer Cache is sub-divided by Oracle into units of
storage called “blocks”. Blocks are the smallest unit of storage in Oracle and you control
the data file blocksize when you allocate your database files.
An Oracle block is different from a disk block. An Oracle block is a logical construct -- a
creation of Oracle, rather than the internal block size of the operating system. In other
words, you provide Oracle with a big whiteboard, and Oracle takes pens and draws a
bunch of boxes on the board that are all the same size. The whiteboard is the memory,
and the boxes that Oracle creates are individual blocks in the memory.
Each block inside a file is determined by your db_block_size parameter and the size of
your “default” blocks are defined when the database is created. You control the default
database block size, and you can also define tablespaces with different block sizes. For
example, many Oracle professionals place indexes in a 32k block size and leave the data
files in a 16k block size.
Inside the Shared Pool
The Oracle shared pool contains Oracle's library cache, which is responsible for
collecting, parsing, interpreting, and executing all of the SQL statements that go against
the Oracle database. Hence, the shared pool is a key component, so it's necessary for
the Oracle database administrator to check for shared pool contention.
The shared pool is like a buffer for SQL statements. Oracle's parsing algorithm ensures
that identical SQL statements do not have to be parsed each time they're executed. The
shared pool is used to store SQL statements, and it includes the following components:
* The library cache
* The dictionary cache
* Control structures
The following table lists the different areas stored in the shared pool and their purpose:
* Shared SQL Area - The shared SQL area stores each SQL statement executed in the
database. This area allows SQL execution plans to be reused by many users.
* Private SQL Area - Private SQL areas are non-shared memory areas assigned to unique
user sessions.

By Subhash Reddy Aedla Page 56 of 304


ORACLE

* PL/SQL Area - Used to hold parsed and compiled PL/SQL program units, allowing the
execution plans to be shared by many users.
* Control Structures - Common control structure information, for example, lock
information
The dictionary cache stores “metadata” (data about your tables and indexes) and it’s
also known as the row cache. It is used to cache data dictionary related information in
RAM for quick access. The dictionary cache is like the buffer cache, except it’s for Oracle
data dictionary information instead of user information. We will discuss the data
dictionary later in this book.
As with the database buffer cache, the shared pool is critical to performance. Later in
this book we will discuss the concept of Oracle SQL statement reuse. Reusability is a
concept that is very important when it comes to performance relating to the shared
pool!
Thus far we have discussed Oracle’s in-memory storage of data, SQL and control
structures but there is one other very important SGA structure to be mentioned, the
redo log buffer.
The Redo Log Buffer
The redo log buffer is a RAM area (defined by the initialization parameter log_buffer)
that works to save changes to data, in case something fails and Oracle has to put it back
into its original state (a “rollback”). When Oracle SQL updates a table (a process called
Data Manipulation Language, or DML), redo images are created and stored in the redo
log buffer. Since RAM is faster than disk, this makes the storage of redo very fast.
Oracle will eventually flush the redo log buffer to disk. This can happen in a number of
special cases, but what’s really important is that Oracle guarantees that the redo log
buffer will be flushed to disk after a commit operation occurs. When you make changes
in the database you must commit them to make them permanent and visible to other
users.

Oracle commit Processing


A commit is a very important Oracle concept. As users make changes in Oracle, those
changes are only visible to the user session making the change and are unrecoverable in
the case of a crash. A commit changes all that. When the user tells Oracle to commit the
change, Oracle makes the change visible to everyone, and ensures that the change is
recoverable.

By Subhash Reddy Aedla Page 57 of 304


ORACLE

Since RAM is wiped out if you lose power to the computer, all the redo data in the redo
buffer would be lost in a power outage. To protect against this problem, a commit asks
Oracle to save the redo to disk, which is permanent. The redo log disk files are called
online redo logs.
Oracle PGA Concepts
Not all RAM in Oracle is shared memory. When you start a user process, that process
has a private RAM area, used for sorting SQL results and managing special joins called
“hash” joins. This private RAM is known as the Program Global Area (PGA). Each
individual PGA memory area is allocated each time a new user connects to the
database.
Oracle Database 10g will manage the PGA for you if you set the pga_aggregate_target
parameter (we will discuss parameters and how they are set later in this book), but you
can manually allocate the size of the PGA via parameters such as sort_area_size and
hash_area_size. We recommend that you allow Oracle to configure these areas, and just
configure the pga_aggregate_target parameter.
The PGA can be critical to performance, particularly if your application is doing a large
number of sorts. Sort operations occur if you use ORDER by and GROUP BY commands
in your SQL statements.

Oracle Installation Concepts


We are now ready to move-on and take a look at how to create and install an Oracle
database.
Installing Oracle and Creating a new Oracle Database
In this chapter we will discuss how you install the Oracle database software and then
show you how you create an Oracle database. Finally, after you have created your
Oracle database we will discuss the SQL*Plus interface to the Oracle database.
Installing and Creating Oracle Databases
Before you can create an Oracle database, you must first install the database software.
The software for Oracle Database 10g comes on only one CD, so installation is easy. In
this section we will discuss what you need to do before you install the Oracle software
and then we will discuss the installation of the Oracle software.
Before you install the Oracle software, you need to make sure you are using the right
edition and version of Oracle.
There is a separate install guide for each hardware platform and it’s critical that you
read this manual before trying to install Oracle.

By Subhash Reddy Aedla Page 58 of 304


ORACLE

You would be amazed at how many times I’ve seem basic questions asked in forums
where it’s clear the person asking the question had not read the instillation guide. I’ve
been told that the DBA guild is considering doubling its rates for any emergency calls to
fix install disasters, so read up folks! Let’s get started.
Checking the Edition and Version of Oracle
When preparing to install the Oracle software for the first time, you need determine the
release and features that you desire. When considering what version of Oracle to use,
consider the following issues:
1. Features - Different versions of the Oracle database software have different
functionality. Versions in Oracle are numbered, like 9.2.0.6 or 10.1.0.3, and they indicate
the release level of the software. Go to Oracle’s web site, www.oracle.com, to find out
what features are available in the version of Oracle you are planning to use.
2. Edition - Oracle version is one consideration, but in each version there are editions
that come with different functionality. Make sure that the features you will need to use
are available in your edition of Oracle. The names change with each release, but Oracle
Database 10g comes in Enterprise Edition, Standard Edition and Personal Edition.
Advanced functionality is missing from Standard Edition (SE) and Express Edition (XE).
3. Version - Make sure that the version you are installing is still supported by Oracle, and
that it will not soon be de-supported. You should do this because it can be very time
consuming (and sometimes expensive) to migrate to different versions of Oracle.

Using the Oracle Universal Installer


The Oracle installer is called the Oracle Universal Installer (OUI). Written in Java, OUI has
the same look-and-feel on any of Oracle’s 60+ supported platforms. One of the nice new
features of Oracle Database 10g is that the installer only needs to use one CD (in
previous versions there were up to 3 different CD’s). Of course, additional CD’s are
required to load optional products.
If you don’t have access to Oracle CD’s, you can download the Oracle Database software
from Oracle Corporations web site at www.oracle.com.
The download is free for non-commercial use, and you will need to purchase a license if
you want to use it for purposes other than learning.
To start the Oracle installer on a Windows environment, you simply put the Oracle
Database 10g CD in the CDROM drive and the autorun will start the installer. If you have
autorun disabled, simply double click setup from the CD.

By Subhash Reddy Aedla Page 59 of 304


ORACLE

If you are running on another platform, follow the directions in the platform-specific
install instructions:
 Mounting the CD
 Changing to the CD mount point (don’t do this if you are installing 9i or you
won’t be able to eject the CD on linux or UNIX platforms!)
 Running the installer. In UNIX this is typically called runInstaller.
The Oracle installer makes the install process quite easy and you simply follow the
prompts. Let’s look at a typical install and see just how easy it is!
Tip: If you are trying to run the Oracle installer on UNIX, you need to make sure you can
start an X-windows session on the console you are using! You must be able to run X in
order for the Oracle installer to function correctly.
What we have gone over is the “quick and dirty” installation and setup of Oracle on your
computer. While there are many more options available during the installation phase,
they are things you will be working with in time.
The main points of this chapter include:
 The Oracle Universal installer will guide you through the installation process.
 There are several steps to installing Oracle, including the loading of the
executables and the creation of databases.
 Oracle provides the Database Creation Assistant (DBCA) to help us create
databases.
In the chapters to come, we will use Oracle in many different ways. Through the
information you will gain from these chapters, you will begin to understand more of the
advanced options that can be performed as early as the installation phase of the
software.

Installing the Oracle Software


Once you have started the installer, the first screen you will see is the welcome screen:
In this example, we will do a typical install, without creating the starter database so we
un-check the Create Starter Database box.
If you need to install Oracle on another disk drive, you can enter the new location in the
box titled Oracle Home Location. Now, press the Next button.
At this point, Oracle will collect information about your server environment. For
example, you may get occasional errors that say that Oracle cannot determine your IP

By Subhash Reddy Aedla Page 60 of 304


ORACLE

address. This is typical if you are running in a Windows environment where there is a
dynamic IP address. To avoid this, create a temporary entry in your hosts file (operating
system dependent) with the current static IP address of your server.
Once the installer has collected external information it will present you a summary
screen of all the products that you may install.
At this point, click the install button and Oracle will begin to install the database
software on your computer. As it works, you will see a thermometer that displays the
progress of the install:
The install may take up to ten minutes, so just be patient as it loads and links the
executables. You can stop the install by clicking on the stop installation button.
Once the install is complete you will see the following screen:
This screen gives you a lot of information, and you will want to note the Ultra Search
URL and the iSQL*Plus URL. When the end of installation screen appears the install is
complete and you can click on the exit button to exit the installer.
Tip: On UNIX platforms you will also need to run a script called root.sh during the install
as the “root” user.

Connecting to your Oracle Database


There are a number of ways to log into your newly created Oracle database.
Programmers will use things like ODBC, JDBC and OCI to connect to your database from
their application. You, the DBA, have a number of tools available to you that allow you
to connect to and manage your database including SQL*Plus and Oracle Enterprise
Manager (OEM). Also a number of third party tools are available for you to use that can
help you manage your Oracle database
Connecting to the Database with the SQL*Plus Client
In this section, we are interested in the principle DBA interface into Oracle,
SQL*Plus. There are two versions of SQL*Plus readily available. The first is the SQL*Plus
client version which can be installed on any Windows based PC.
To start the SQL*Plus client from Windows click on start->Your_oracle_home_location-
>application development-> SQL Plus. When you do, you will see the SQL*Plus login
screen:
We just created our database in DBCA, and assigned a password to the DBA
management account SYS. Now we want to log in as SYS. To do so, we enter the
connection below:

By Subhash Reddy Aedla Page 61 of 304


ORACLE

In this case, we are connecting to the SYS account of the database we just created. The
SYS account is an all powerful account in Oracle, and it should never be used lightly.
Notice the host string setting. Here we put in our database name (booktest), and we
added the syntax as sysdba. Most non-DBA’s will never use the as sysdba command, for
it implies special privileges are granted to the person logging in. In your case, you are a
DBA, so you need the special privileges that as sysdba provides.
At this point, you will be logged into Oracle, and SQL*Plus will be ready to accept your
commands. FYI, there is another version of SQL*Plus out there, called iSQL*Plus, with
an Internet interface.
This screen print shows you what the SQL*Plus client looks like once it comes up:

The SQL*Plus Command Line Interface


SQL*Plus also comes with a command line interface. This is the interface you use when
working from the command line. To start SQL*Plus at the command line you must do
the following:
1. If connecting to a local database you must set the ORACLE_SID environment
parameter to the name of your database. Here is an example of doing this in Windows,
followed by an example of setting the ORACLE_SID in UNIX (as well as Oracle Home and
path information so Unix can find the binaries):
Windows:
C:>Set ORACLE_SID=booktst
UNIX/Linux:
export ORACLE_SID=booktst

export ORACLE_HOME=your_install_location

export PATH=$PATH:$ORACLE_HOME/bin

2. Next, we start SQL*Plus with the sqlplus command. When starting SQL plus include
the user name that you wish to connect to. Here are examples of the use of this
command:
C:\>sqlplus john_dba

SQL*Plus: Release 10.1.0.2.0 - Production on Sun Feb 20 11:28:13 2005

Copyright (c) 1982, 2004, Oracle. All rights reserved.

Enter password:

Connected to:

Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - Production

With the Partitioning, OLAP and Data Mining options

By Subhash Reddy Aedla Page 62 of 304


ORACLE

SQL>

Note in the example above that when you start SQL*Plus, you must provide the name of
the user account. In this case, we logged into the account john_dba. Next, SQL*Plus will
prompt you for the password to this account. If you enter the correct password (you will
not be able to see the password when you enter it in) then Oracle will pass you to the
SQL prompt (SQL>).
You can also include the password when you call SQL*Plus, but this means that your
password will not be hidden, and this can have serious security implications. Here is an
example of using the user account and the password to log into SQL*Plus:
/u01/app> sqlplus john_dba/my_password
If you do this in a UNIX/Linux environment, the command “ps –ef” will display your
password for anyone to see.
To perform specific DBA activities on the database (such as backing up the database or
shutting it down), you will need to log in as a special type of user. This is because these
operations require a special set of administrative privileges called the SYSDBA and
SYSOPER privileges.
To activate these privileges, your user ID must be allowed to access these privileges (we
will discuss setting up such an account later in this book) and you must use a special
connection string to connect to the database to activate these privileges. If you want to
connect using the SYSDBA privileges (these are super DBA privileges) then use the
following syntax:
C:\>sqlplus “sys as sysdba”
You can also include the password if you prefer:
C:\>sqlplus “sys/my_password as sysdba”
The same method of connecting also works with the SYSOPER privilege. You simply
replace sysdba with sysoper in the connection string. One final thing to notice is that the
connection string is enclosed in quotes. This is required because there is white space
(blanks) inside the connection string.

By Subhash Reddy Aedla Page 63 of 304


ORACLE

Oracle Internal Data Types


In order to create a table we need to specify a data type for individual columns in the
create table command. Oracle supports the following data types, to achieve the above
requirements.
1. Char
2. Varchar, Varchar2
3. Long
4. Number
5. Date
6. Raw
7. Long
8. LOB’s Supported by Oracle 8i onwards

CLOB
BLOB
BFILE
9. XML : Supported in Oracle 9i
Char data type {1 – 2000 bytes}
It is used when fixed length string is required. It can store alphanumeric values. The
column length of such a data type can vary between 1-2000bytes. By default it is one
byte.
 If the user enters a value shorter than the specific length than the database black
pads to the fixed length.
 In case, if the user enters a value larger than the specified length than the
database would return an error.
Varchar {1 – 4000bytes}
It supports variable length character string. It also stores alphanumeric values. The size
of this data type ranges from 1-4000bytes. Using varchar saves disk space when
compared to char data type. Because if a user is not utilizing the space of this data type
as declared while initializing, depending on this data it will occupy only that space in
disk.

By Subhash Reddy Aedla Page 64 of 304


ORACLE

 Currently varchar2 data type is equivalent to varchar type.


Long data type {2GB}
It is to store variable character length. Maximum size is 2GB. Long data type has several
characters similar to varchar2 data type. Its length would be restricted based on the
available space in the computer memory.
The following are the restrictions needs to be full filled when a long data type is cast on
a column in a table.
1. Only one column in a table can have long type. This should not contain unique or
primary key constraints.
2. This column cannot be indexed.
3. Produces or stored produces cannot accept long data type as arguments.
Number data type
This data type can store +ve, -ve, zeros, fixed point and floating point numbers with a
precision of 38.
 Column name {P=38, S=0}
 Column name (p) {Fixed point}
 Column name (p, s) {Floating point}
P – Precision which refers to the total no of digest, it varies between 1to 38.
S – Scale which refers to number of digests to the right of the decimal point, which
varies between -84to 127.
Date data type {8 bytes each for c, m, d, y, h, mi, se}
It is used to store date and time in a table. Oracle db makes use of its own format to
store data in a fixed length of 8 bytes each for century, month, day, year, hour, minute,
and second. Default date data type is “dd-mon-yy”. To view system’s date and time we
can use the SQL pseudo column called sysdate. Valid date is from jan1, 4712BC to
dec31, 4712AD.
Raw data type {2000 bytes}
It is used to store byte oriented data like binary data or byte strings and the maximum
size of this data type is 2000bytes. While using this data type the size should be
mentioned because by default it does not specify any size. Only storage and retrieval of
data are possible, manipulations of data cannot be done. Raw data type can be indexed.
Long Raw data type {2GB}

By Subhash Reddy Aedla Page 65 of 304


ORACLE

It is to store binary data in variable length, which can have a maximum size of 2GB. This
data type cannot be indexed. Further all limitations faced by long data type also holds
good for long raw data type.
Large Object data types (LOB) {4GB}
It can store unstructured information such as Scanned clips, video files etc., up to 4giga
bytes in size. They allow efficient, random, piece-wise access to data. The LOB types
store values, which are known as Locators. These Locators store the Location of the
large objects.
The location may be out -of-line (not with in table) or in an external file. The DBMS_LOB
package can be used to manipulate LOB’S. LOB’S can be either external or internal
depending on their location with regards to the database. Data stored in a LOB column
is known as LOB value.
Internal LOB’S are stored in the db table space this provides efficient access and
optimization of space. External LOB’S are also referred to as BFILE. These are stored in
operating system files outside the db table space. The files use reference semantics.
They may be stored in CD-ROM’S, photo CD’S, or hard disks etc. but the storage cannot
extend from one device to another. The external LOB’S do not participate in
transactions.
Changes to internal LOB’S can be done using SQL DML, packages provided in PL/SQL
called DBMS _LOB. Changes can also be done through series of API calls from the Oracle
call Interference (OCI). Changes can be made to entire Internal LOB, or piece wise to the
beginning, middle or end of the Internal LOB. Both Internal and External LOBS can be
accessed for read purpose.
PL/SQL provides a set of intrinsic data types for the support of LOB’S, although SQL
cannot directly manipulate these data types, they are accessible from SQL through
PL/SQL function calls.
The different Internal LOB’S are:
CLOB
BLOB
BFILE
CLOB
A column with its data type as CLOB stores characters objects with single byte
characters. It cannot contain character sets of varying widths. A table can have multiple
columns as its data type.
BLOB

By Subhash Reddy Aedla Page 66 of 304


ORACLE

A column with its data type as BLOB can store large binary objects such as graphics,
video clips and sound files. A table can have multiple columns with BLOB as its data
type.
BFILE
A Bfile column stores file pointers to LOB’S managed by file systems external to
database. A Bfile column may contain file names for photos stored on a CD-ROM.
For the sake of backward compatibility Oracle 9i supports all other data types such as
RAW and LONG RAW. The LOB data types have several advantages over the data types
already present in previous versions of Oracle.
The advantages are:
1. A table can have multiple LOB columns.
2. Multiple LOB’s are allowed in a single row.
3. LOB’S can be attributes of a user defined data type.
4. A table stores small Locators for the LOB’S in a column in place of the actual
objects. In contract a table stores the LONG column within the table itself.
5. A LOB column can have storage characteristics different from those for the table.
It is possible to separate the primary table data from those of the LOB columns
to different Locations.
6. Accessing the LOB column returns the Locators.
7. The maximum size of a LOB column is 4GB.
8. Applications can manipulate and access pieces of the LOB. However, for LONG
data type the entire data must be accessed.
LOB column can be indexed. The index on the LOB column cannot be dropped and
rebuilt.
The user can specify setting of internal LOB’S to null or empty. An empty LOB stored in a
table is a LOB of zero length and is assigned a Locator. This Locator can have been used
to populate the LOB Later.
A table space can be referred to as Logical storage units which make up the database. It
is normally the job of DBA to create, add and drop a table space through a user can also
perform the same. Defining a table space for the LOB is optional.
List of datatypes available in Oracle.

By Subhash Reddy Aedla Page 67 of 304


ORACLE

Character Datatypes
Data Type Oracle 9i Oracle 10g Oracle 11g Explanation
Syntax (if applicable)

char(size) Maximum size of Maximum size of Maximum size of Where size is the number of characters to store.
2000 bytes. 2000 bytes. 2000 bytes. Fixed-length strings. Space padded.

nchar(size) Maximum size of Maximum size of Maximum size of Where size is the number of characters to store.
2000 bytes. 2000 bytes. 2000 bytes. Fixed-length NLS string Space padded.

nvarchar2(size) Maximum size of Maximum size of Maximum size of Where size is the number of characters to store.
4000 bytes. 4000 bytes. 4000 bytes. Variable-length NLS string.

varchar2(size) Maximum size of Maximum size of Maximum size of Where size is the number of characters to store.
4000 bytes. 4000 bytes. 4000 bytes. Variable-length string.

long Maximum size of Maximum size of Maximum size of Variable-length strings. (backward compatible)
2GB. 2GB. 2GB.

raw Maximum size of Maximum size of Maximum size of Variable-length binary strings
2000 bytes. 2000 bytes. 2000 bytes.

long raw Maximum size of Maximum size of Maximum size of Variable-length binary strings. (backward
2GB. 2GB. 2GB. compatible)

Numeric Datatypes
Data Type Oracle 9i Oracle 10g Oracle 11g Explanation
Syntax (if applicable)

number(p,s) Precision can Precision can Precision can Where p is the precision and s is the scale.
range from 1 to range from 1 to range from 1 to
For example, number(7,2) is a number that has 5
38. 38. 38.
digits before the decimal and 2 digits after the
Scale can range Scale can range Scale can range
decimal.
from -84 to 127. from -84 to 127. from -84 to 127.

numeric(p,s) Precision can Precision can Precision can Where p is the precision and s is the scale.
range from 1 to range from 1 to range from 1 to
For example, numeric(7,2) is a number that has 5
38. 38. 38.
digits before the decimal and 2 digits after the
decimal.

float

dec(p,s) Precision can Precision can Precision can Where p is the precision and s is the scale.
range from 1 to range from 1 to range from 1 to
For example, dec(3,1) is a number that has 2 digits
38. 38. 38.
before the decimal and 1 digit after the decimal.

decimal(p,s) Precision can Precision can Precision can Where p is the precision and s is the scale.
range from 1 to range from 1 to range from 1 to
For example, decimal(3,1) is a number that has 2
38. 38. 38.
digits before the decimal and 1 digit after the
decimal.

By Subhash Reddy Aedla Page 68 of 304


ORACLE

integer

int

smallint

real

double
precision

Date/Time Datatypes
Data Type Oracle 9i Oracle 10g Oracle 11g Explanation
Syntax (if applicable)

date A date between Jan 1, A date between Jan 1, A date between Jan 1,
4712 BC and Dec 31, 4712 BC and Dec 31, 4712 BC and Dec 31,
9999 AD. 9999 AD. 9999 AD.

timestamp fractional seconds fractional seconds fractional seconds Includes year, month, day, hour,
(fractional seconds precision must be a precision must be a precision must be a minute, and seconds.
precision) number between 0 and number between 0 and number between 0 and
For example:
9. (default is 6) 9. (default is 6) 9. (default is 6)
timestamp(6)

timestamp fractional seconds fractional seconds fractional seconds Includes year, month, day, hour,
(fractional seconds precision must be a precision must be a precision must be a minute, and seconds; with a
precision) with time number between 0 and number between 0 and number between 0 and time zone displacement value.
zone 9. (default is 6) 9. (default is 6) 9. (default is 6)
For example:
timestamp(5) with time zone

timestamp fractional seconds fractional seconds fractional seconds Includes year, month, day, hour,
(fractional seconds precision must be a precision must be a precision must be a minute, and seconds; with a
precision) with local number between 0 and number between 0 and number between 0 and time zone expressed as the
time zone 9. (default is 6) 9. (default is 6) 9. (default is 6) session time zone.

For example:
timestamp(4) with local time
zone

interval year year precision is the year precision is the year precision is the Time period stored in years and
(year precision) number of digits in the number of digits in the number of digits in the months.
to month year. (default is 2) year. (default is 2) year. (default is 2)
For example:
interval year(4) to month

interval day day precision must be day precision must be day precision must be Time period stored in days,
(day precision) a number between 0 a number between 0 a number between 0 hours, minutes, and seconds.
to second (fractional and 9. (default is 2) and 9. (default is 2) and 9. (default is 2)
For example:
seconds precision)
fractional seconds fractional seconds fractional seconds interval day(2) to second(6)
precision must be a precision must be a precision must be a
number between 0 and number between 0 and number between 0 and
9. (default is 6) 9. (default is 6) 9. (default is 6)

By Subhash Reddy Aedla Page 69 of 304


ORACLE

Large Object (LOB) Datatypes


Data Oracle 9i Oracle 10g Oracle 11g Explanation
Type (if applicable)
Syntax

32 64
bfile Maximum file Maximum file size of 2 -1 bytes. Maximum file size of 2 -1 bytes. File locators that point to a
size of 4GB. binary file on the server file
system (outside the database).

blob Store up to 4GB Store up to (4 gigabytes -1) * (the Store up to (4 gigabytes -1) * (the Stores unstructured binary
of binary data. value of the CHUNK parameter of value of the CHUNK parameter of large objects.
LOB storage). LOB storage).

clob Store up to 4GB Store up to (4 gigabytes -1) * (the Store up to (4 gigabytes -1) * (the Stores single-byte and multi-
of character value of the CHUNK parameter of value of the CHUNK parameter of byte character data.
data. LOB storage) of character data. LOB storage) of character data.

nclob Store up to 4GB Store up to (4 gigabytes -1) * (the Store up to (4 gigabytes -1) * (the Stores unicode data.
of character text value of the CHUNK parameter of value of the CHUNK parameter of
data. LOB storage) of character text LOB storage) of character text
data. data.

By Subhash Reddy Aedla Page 70 of 304


ORACLE

SQL Commands
Data Definition Language
It is used to create an object (e.g., Table), alter the structure of an object and also to
drop the object created.
Table Definition
A table is a unit of storage that holds data in the form of rows and columns. The DDL
used for table definition can be classified into following four:
1. Create Table command
2. Alter Table command
3. Truncate Table command
4. Drop Table command
Syntax for creating table:
Create Table <table name> (Column Definition, Column Definition,…);
In a Table
 We should specify a unique column name.
 We should specify proper data type along with its width.
Example
Create Table test (no number(3), name varchar2(10), fee number(7,2));
Table name should adhere strictly the following norms:
1. While naming a table the first letter should be an alphabet.
2. Oracle reserved words cannot be used to name a table.
3. Maximum length for a table name is 30 characters
4. Two different tables should not have same name
5. Underscore, numerals and letters allowed but not blank space and single quotes
If the user uses double quotes for naming the table likes “inf” then upper and lower
case are not equivalent.
Syntax to alter a table:
Alter table < table name > modify (column def);

By Subhash Reddy Aedla Page 71 of 304


ORACLE

Alter table <table name > add (column def);


Alter table commands cater to the need arising out of the following situations:
When a user wants to add a new column
To change the width of a data type or data type itself
To include or drop integrity constraints
We can decrease the length of existing column data type provided the table is empty.
No such restrictions are imposed while increasing the length of an existing table.
Examples:
Alter table test modify (name char (10));
Alter table test modify (fees number (52));
Alter table test modify (no number);
Alter table test modify (name varchar2 (8));
Alter table test add (course varchar (7));
Syntax to truncate table:
This command is used to delete all the records from an existing table, retaining the
structure of that table
Truncate table <table name>;
Example:
Truncate table test;
By using ‘reuse storage’ clause to the same command the space that is used for the
storage can be reclaimed.
Example:
Truncate table test reuse storage;
Even though the result of both the above truncate commands are same. Oracle
internally reclaims the space of the deleted rows for future use.
In order to view the structure of any table use Desk test <table name>
Desk test
If lists column of table along with their data types.
Command to drop a table

By Subhash Reddy Aedla Page 72 of 304


ORACLE

Drop table <table name>


Drop table test;

Data Manipulation Language


DML commands are used to query processing and manipulate existing objects like
tables.
Insert command
While using this command the values are separated by commas and the data type’s
varchar2, char, raw, long and date are enclosed in single quotes.
The values must be entered in the same order as they are defined in the table.
If data has to be written into only specific columns this too is possible with slight
variations to the general syntax.
Insert into <table> values (a list of data values);
Insert into test values (&no, ‘&name’, &fees);
Insert into test values (111, ‘Anil’, 5000);
Insert into test values (112, ‘Atul ’, 4500.25);
Insert into test (no, name) values (113, ‘Akhil’);
Select command
The select command is most frequently used command so as to access information from
database. This is generally referred to as ‘querying’ the table.
Syntax
Select column name, …… from <table name> ;
Example
select * from emp;
Select empno, ename, dept, job, salary from emp;
Selecting distinct Rows
To prevent the selection of duplicate rows, we include distinct clause in the select
command. Suppose there are duplicate values in emp table. The following query would
exclude them from being displayed.
Select distinct mgr from emp;
Select distinct deptno from emp;

By Subhash Reddy Aedla Page 73 of 304


ORACLE

The effect of distinct clause is clear if we select any particular field or else if we select
two columns and add distinct clause to one column it has no effect, because at that
instant this distinct clause concentrates on both of those fields.
Select command with where clause
Select * from emp where empno = 7788;
Select * from emp where sal > 5000;
Select * from emp where sal < 5000;
Select * from emp where job = ‘MANAGER’;
Select *from emp where job like ‘MANAGER’;
Select * from emp where ename like ‘S%’;
To select specific rows from a table we include a ‘where’ clause in the select command.
It can appear only after the ‘from’ clause. We can retrieve only the rows which satisfy
the ‘where’ condition.
To arrange the displayed rows according to some pre-defined order we can use the
‘order by’ clause. It is also used to arrange rows in ascending and descending order. The
order clause can also be used to arrange multiple columns.
Note: The ‘order by’ clause should be the last clause in the select command.
The ‘where’ clause in a select command which retrieves specific rows from a table is
also applicable to delete and update row or rows from a table according to the
conditions specified by the where clause.
Select * from emp order by sal;
Select * from emp order by empno;
Select * from emp order by hiredate;
Select * from emp order by sal desc;
Select * from emp order by empno desc;
Select * from emp order by hiredate desc;
Select * from emp where sal > 5000 order by sal desc.
Update command
Some times changes to the database become imminent and to reflect these changes to
the existing records in a table the update command is used. With this update command

By Subhash Reddy Aedla Page 74 of 304


ORACLE

we can update rows in a table. A single column or multiple columns could be updated.
Specific rows could be updated based on a specific condition.
The update command consists of a ‘set’ clause and an optional where clause.
Syntax
Update <table> set field = value, ….where <condition>;
Update emp set sal = 3000 where empno = 115;
Update emp set job = ‘Manager’ where sal = 3000;
Update emp set hiredate = ’12-jan-98’ where empno = 111;
Delete command
This command is used to delete existing rows, the delete command consists of a ‘from’
clause followed by an optical ‘where’ clause.
Syntax
Delete from <table name> where <conditions>;
Using this delete command not only specific records rather all the records for a table
can be deleted without affecting the structure of the table.
Example
Delete from emp where empno = 111;
The above query deletes the record where empno is 111.
Delete from emp where sal <3000;
The above query deletes all the records where its sal is lesser than 3000;

Transaction Control Language


A transaction is a logical unit of work. All the changes made to database can be referred
as a transaction. Transaction changes can be made permanent to a database only if they
are committed. A transaction begins with an executable SQL statement and ends
explicitly with either rollback or commit statement, and implicitly, i.e., automatically,
when DDL statements are used.
Commit command
This command is used to end the transaction. Only with the help of the help of the
commit command, transaction changes can be permanent to the database. This
command also erases all the save points in the transaction thus releasing the
transaction locks.

By Subhash Reddy Aedla Page 75 of 304


ORACLE

Syntax
Commit work; (or)
Commit;
Save point
Save points are like markers to divide a very lengthy transaction to smaller ones. They
are used to identify a point in a transaction to which we can later rollback. Thus save
point is used in conjunction with rollback, to rollback portions of the current
transactions.
Syntax
Save point savepoint_id;
Rollback
A rollback is used to undo the work done in the current transaction. We can either
rollback the entire transaction so that all changes made by SQL statements are undo, or
rollback a transaction to a save point so that the SQL statements after the save points
are rolled back.
Syntax
Rollback work;
Rollback;
Rollback to save point save point_id;
Example
update emp set hiredate =’30-jan-98’where empno =1111;
Save point S1;
Delete from emp where empno =1111;
Save point S2;
Rollback to save point S1;
Rollback;
Select command’s Group By:
This is another optional part of the query. It is used only when the results of the query
have to be grouped based on criteria.
For ex: if the average salary of employees in a dept is to be found.

By Subhash Reddy Aedla Page 76 of 304


ORACLE

Select deptno, avg(sal) from emp where deptno = 20;

Data Control Language


It provides user with privilege commands. The owner of database object (table) has sole
authority over them. The owner can allow other database users access to objects as per
his discretion. Granting privileges (insert, select……) to others allows them to perform
operations with in their privileges. Privileges granted can also be withdrawn by the
owner at any time.
Grant privilege command
If user wants to share his objects with others, the appropriate privileges can be granted
on that particular object to others. Objects are logical data storage structures like tables,
views, sequences, indexes, synonyms etc.
Syntax
Grant privileges on <object name> to <user name>;
Examples
Grant select, update on emp to <user name>;
Grant update (sal, comm) on emp to <user name>;
Grant all on emp to <user name>;
Revoke privilege command
To withdraw the privileges that has been granted by a user, we use the revoke
command. This command is closely similar to that of the grant command in its format.
Syntax
Revoke privileges on <object name> from <user name>;
Example
Revoke select, update on emp from <user name>;
Revoke update on emp from <user name>;
Revoke all on emp from <user name>;

By Subhash Reddy Aedla Page 77 of 304


ORACLE

Query Processing
Different select statements
Apart from just providing information this command can be clubbed with some DDL and
DML statements to perform relational operations.
Select command to create table
Syntax
Create table <table name> as select * from <another table name>;
Create table <new table> as select clmn1, clmn2 from <old table>;
Create table <new table> (clmn1, clmn2) as select clmn1, clmn2 from <old table>;
Create table <new table> as select * from <old table> where <condition>;
Create table <new table> as select * from <old table> where 1=2;
The above syntax creates a table with the structure of old without copying its data.
Examples
Create table newemp as select * from emp;
Create table emp1 as select empno, ename, sal from emp;
Create table emp2 (No, Name, Salary, desig) as select empno, ename, sal job from emp;
Create table emp3 as select * from emp where sal <5000;
Create table emp4 as select * from emp where hiredate <’01-jan-90’;
Create table emp5as select * from emp where 1=2;
The condition 1=2 will never satisfy. Hence a new table will be created with only the
structure of the emp table but not its records.
Select command to insert records
Alternatively inserting records from one table into another can also be accomplished. In
this case either a table should be created or exist prior to performing such an insert.
Syntax
Insert into <table1> (select * from <table2>);
Insert into<table1> (select c1, c2 from <table2>);
Note: Care should be taken to ensure that the two tables’ structures are the same.
Examples

By Subhash Reddy Aedla Page 78 of 304


ORACLE

Insert into emp5 (select * from emp);


Insert into emp2 (select empno, ename, sal, job from emp);
Select command for column Aliases
Syntax
Select col_name <alias_name> from <table_name>;
Example
Select empno number, ename name, job designation from emp;
Operators in SQL*Plus
1. Arithmetic operators : +, -, *, /
2. Comparison operators : =, !=, <, >, <=, >=
3. Logical operators : AND, NOT, OR
Arithmetic Operators
Select ename, sal - comm from emp;
Select ename, sal + comm from emp;
Select ename, sal * 12 annual pay from emp;
Comparison operators
They are used in conditions to compare one expression with another. The comparison
operators are =, !=, <, >, <=, >=.
Between: It is used in conditions to check the values between any two.
In: It is used to match with any values in the list.
Like: It is used to match a character pattern
Is Null: It is used to check whether it is null or not.
Examples
Select * from emp where sal < 3000;
Select * from emp where sal > 3000;
Select * from emp where ename = ‘SCOTT’;
Select * from emp where ename != ‘SCOTT’;
Select * from emp where sal between 1000 and 4000;

By Subhash Reddy Aedla Page 79 of 304


ORACLE

Select * from emp where hiredate in (‘01-jan-81’ ‘09-nov-82’);


It will list all the employee records whose hiredates lies in the given list.
In operator can be used to select rows that match one of the values in the list.
Select * from emp where ename like ‘M%’;
Select * from emp where ename like ‘%R’;
Select * from emp where ename like ‘%D%’;
Select * from emp where comm is null;
Select * from emp where comm. is not null;
Logical operators
A logical operator is used to combine the results of two conditions to produce a single
result. The logical operators are AND, NOT, OR.
Example
Select * from emp where hiredate > ’10-may-98’ and sal < 3000;
Select * from emp where sal >3000 and job= ‘MANAGER’;
Select * from emp where not sal > 3000;
Select * from emp where not job = ‘MANAGER’;
Select * from emp where sal > 3000 or job = ‘MANAGER’;
DUAL
Dual is a small but useful Oracle table created for testing functions or doing quick
calculations.
Examples
Select 100+200 from dual;
Select (100+300)*5 from dual
Select ‘SCOTT’ from dual;
Select ((100+200-150)*2)/3 from dual;

By Subhash Reddy Aedla Page 80 of 304


ORACLE

SQL*Plus Functions
SQL*Plus provides specialized functions to perform operations using the DML
commands. A function takes one or more arguments and returns a value. One can
broadly classify functions into single row functions and group functions.

Numeric functions
These functions accept numeric input and returns numeric values as out put. The values
that the numeric functions returns are accurate up to 38 decimal digits.
Absolute value (Abs)
Absolute value is the measurement of the magnitude of something. For instance, in a
temperature change or a stock index change, the magnitude of the change has meaning
in itself, regardless of the direction of the change. Absolute value is always a positive
number.
ABS (value)
Select abs (-15) from dual; o/p=15
Ceiling (CEIL)
It simply produces the smallest integer (or whole number) that is greater than or equal
to specific value. Pay special attention to its effect on negative numbers.
CEIL (value)
Select ceil (44.778) from dual; =>45
Select ceil (1.3) from dual; =>2
Select ceil (-2) from dual; =>-2
Select ceil (-2.3) from dual; =>-2
Floor
It is the intuitive opposite of ceil.
Select floor (100.2) from dual; =>100
Select floor (100.3) from dual;
Select floor (-100) from dual;
Select floor (-100.3) from dual;
Modulus (MOD)

By Subhash Reddy Aedla Page 81 of 304


ORACLE

MOD (value, divisor)


Select mod (100, 10) from dual; => 0
Select mod (22, 23) from dual; => 22
Select mod (10, 3) from dual; => 1
Power
It is simply the ability to raise a value to a given positive exponent.
Power (value, exponent)
Select power (3, 2) from dual; => 9
Select power (3, 3) from dual; => 27
Select power (64, .5) from dual; => 8
Square root (sqrt)
Select sqrt (64) from dual;
Select sqrt (625) from dual;
Select sqrt (25) from dual;
EXP (Exponent)
Select exp (3) from dual; => 20-085537
Select exp (4) from dual; => 54.59815
Logarithm (Ln)
Select Ln (2) from dual; => 0.69314718
Select Ln (3) from dual; => 1-0986123
Select Ln (20.085536) from dual; =>3
Round
It rounds number to given no of digits of precision.
Round (value, precision)
Select round (100.256, 2) from dual; =>100.26
Select round (55.5, 0) from dual;
Select round (333.333, 2) from dual;
Truncate

By Subhash Reddy Aedla Page 82 of 304


ORACLE

It truncates or chops off, digits of precisions from a number.


Select trunc (100.256, 2) from dual; 100.25
Select trunc (55.555, 2) from dual;
SIGN
It is flip side of absolute value. Where as ABS tells you the magnitude of a value but not
its sign. Sign tells you the sign of value but not its magnitude.
Select sign (146) from dual; =>1
Select sign (-30) from dual; =>-1
Sign (0) = 0
SIN, SINH, COS, COSH, TAN, TANH, ACOS, ATAN, ATANZ, and ASIN
Select sin (30 * 3.141593/180) = .5
Select cosh (0) from dual; = 1
Select cos (180) from dual;

Character functions
Character functions accept character input and return either character or number
values. The character functions supported by oracle are listed below.
Initcap (char)
Select initcap (‘hello’) from dual;
Select initcap (this-is _a. test, of : punctuation ; for + initcap) from dual;
Lower (char)
Select lower (‘FUN’) from dual;
Upper (char):
Select upper (‘fun’) from dual;
Intcap
It puts the first letter of every word into uppercase, it determines the beginning of a
word based on its being preceded by any character other than a letter.
Ltrim (char, set)
Returns a string that has all characters removed uptill the set specified.
Select Ltrim (‘xyzadams’, ‘xyz’) from dual;

By Subhash Reddy Aedla Page 83 of 304


ORACLE

From the above query the characters xyz from the left of string will be removed and rest
of the characters will be displayed.
Select Ltrim (‘RDBMS’, ‘R’) from dual;
Select Ltrim (‘what’, ‘W’) from dual;
Select Ltrim (‘display’, ‘dis’) from dual;
Rtrim (char, set)
Returns the string with the final characters removed after the last character that is not
in the character set.
Select rtrim (‘character’, ‘acter’) from dual;
Select rtrim (‘given’, ‘n’) from dual;
Select rtrim (‘example’, ‘ple’) from dual;
Select rtrim (‘sunil’, ‘il’) from dual;
Translate (char, from, to)
It converts characters in a string into different characters, based on a substitution plan
you give it, from “from” to “to”.
Select translate (‘Now Vowels are under attack’,’ taeious’, TAEIOUS’) from dual;
O/P => Now VOwEls ArE UndEr ATTACK:
Select translate (‘jack’, ‘j’, ‘b’) from dual;
Select translate (‘soundex’, ‘x’, ‘d’) from dual;
Select translate (‘consider the following example’, ‘aeiou’, ‘AEIOU’);
O/P: cOnsIdEr thE fOllOwIng ExAmplE.
Replace (string, search string, [restring])
Returns a string with every occurance of the specified string replaced with another
string.
Select replace (‘jack and jue’, ‘j’, ‘bl’) from dual;
Select replace (‘george’, ‘ge’, ‘null’) from dual;
Select replace (‘quality’, ‘q’, ‘eq’) from dual;
Substr (char, m, n)

By Subhash Reddy Aedla Page 84 of 304


ORACLE

It is used to clip out a piece of a string. m=> referst for beginning character in string n=>
No of characters. If ‘n’is not mentioned then it will start at point ‘m’ and continues till
end of the string.
Select substr (‘abcdefg’, 3, 2) from dual;
Select substr (‘replace’, 3) from dual;
Select substr(‘programs’, 5, 3) from dual;
Soundex
It compares words that spelled differently but sound alike. To use soundex option, you
must precede the search term with an exclamation mark (!), with no space between !
and the search term. During the search, oracle evaluates the soundex values of the
terms in the text index and searches for all words that have same soundex value.
Select ename from emp where soundex (ename)=soundex (‘ ‘);
Chr (number)
This returns the character value for the given number within braces.
Select chr (67) from dual;
ASCII (char)
This returns the decimal equivalent of a character.
Select ascii (‘A’) from dual; 65
Select assii (‘a’) from dual; 97
Length (char)
This function returns the length of input string.
Select length (‘ramesh’) from dual;
Lpad (string, length, symbol)
It returns the string padded on the left hand side with the third argument.
Select Lpad (‘function’, 15, ‘=’) from dual;
Rpad (string, length, symbol)
It returns the string padded on the right hand side with the character / string in the third
argument.
Select rpad (‘function’, 15, ‘*’) from dual;
Concateurtion (||) operator

By Subhash Reddy Aedla Page 85 of 304


ORACLE

This operator is used to merge two or more strings, or a string and a data value
together.
Select (‘the employee’||ename||‘bearing empno=’||empno||’draws’sal||’rupees per
month’) from emp;
Instr ( )
Select * from emp where instr (ename, ‘-‘);

Date functions
Time Zones
AST / ADT Atlantic Standard / Day Light Time
BST / BDT Bering Standard / Day Light Time
CST / CDT Central Standard / Day Light Time
EST / EDT Eastern Standard / Day Light Time
GMT Greenwich Mean Time
HST / HDT Alaska-Hawaii Standard / Day Light Time
MST / MDT Mountain Standard / Day Light Time
NST New Fund Land Standard time
PST / PDT Pacific Standard / Day Light Time
YST / YDT Yukon Standard / Day Light Time
Add_months
This function returns a date after adding a specified date with specified number of
months. The format is add_months (d, n), where d is the date and n represents the
number of months.
Select ename, hiredate, add_months (hiredate, 2) from emp;
Last_day
This function returns the date corresponding to the last day of the month. Format is
last_day(d);
Select hiredate, last_day (hiredate) from emp where hiredate < ’01-nov-81’;
Select sysdate, last_day (hiredate) from emp;
Next_day

By Subhash Reddy Aedla Page 86 of 304


ORACLE

This function returns the day of that day which comes next in our condition. Format is
next_day (sysdate, day);
Select next_day (sysdate, ‘Tuesday’) from dual;
The above query returns the date when it is Tuesday after or system date.
Select next_day (hiredate, ‘Sunday’) from emp;
Month_between
The function returns the number of months between two dates. Format is
months_between (d1, d2,);
Select months_between (hiredate, sysdate) from emp;
If d1 is later than d2, result is positive, if earlier negative, if d1 and d2 are either the
same day of the month or both last days of the months, the result is always an integer,
otherwise Oracle calculates the fractional portion of the result based on a 31-day month
and considers the difference in time components of d1 and d2.
Round
This function returns the date which is rounded to the unit specified by the format
model. Its format is round (d, (fmt)) where d is the date and fmt is the format model.
Fmt is only an option, by default date will be rounded to the nearest day.
Select hiredate, round (hiredate, ‘year’) from emp;
Select hiredate, round (hiredate, ‘month’) from emp;
Select hiredate, round (hiredate, ‘day’) from emp;
The above query causes the date to be rounded by the nearest Sunday.
Select hiredate, round (hiredate) from emp;
The above query does not include fmt, and therefore it is rounded to the nearest day.
Select sysdate, round (sysdate) from dual;
Select sysdate, round (sysdate, ‘year’) from dual;
Select sysdate, round (sysdate, ‘month’) from dual;
Select sysdate, round (sysdate, ‘day’) from dual;
Truncate
This function returns the date with the time portion of the day truncated to the unit
specified by format model. The syntax is trunc (d, (fmt)). If fmt is neglected, then date is
converted to the nearest day.

By Subhash Reddy Aedla Page 87 of 304


ORACLE

Select trunc ,sysdate, ‘year’) from dual;


If the sysdate is ’27-jan-99’, the truncated result will be ’01-jan-99’.
Select trunc (sysdate, ‘month’) from dual;
If the sysdate is ’27-jan-99’, the result will be ’01-feb-99’.
Select trunc (sysdate, ‘day’) from dual;
The result will be ’24-jan-99’, the nearest Sunday for ’27-jan-99’.
Select trunc (sysdate) from dual;
It will get nearest Sunday.
Select trunc(hiredate, ’year’) from emp;
Select trunc(hiredate, ’month’) from emp;
Select trunc(hiredate, ’day’) from emp;
Select trunc(hiredate) from emp;
Greatest
This function returns the latest date present in the argument. Its format is greatest (d1,
d2)
Examples:
Select hiredate, sysdate, greatest (hiredate, sysdate) from emp;
Least: picks earliest date from list of dates. Its format is least {d1, d2, d3)
New _ time
This function displays the time and date of a date column or literal date in order time
zones. Its format is new _ time (date, ‘this’, ‘other’);
This: it is replaced by a three letter abbreviation of the correct time zone while ‘other’ is
replaced by a three letter abbreviation of the zone in which the date is wanted.
Select new _ time (’13-feb-99’, ‘est’, ‘yst’) from dual
“ (5ysdate, ‘est’, ‘Ast’) “
“ (5ysdate, ‘est’, ‘Bst’) “
“ (5ysdate, ‘est’, ‘Cst’) “
“ (5ysdate, ‘est’, ‘Gmt’) “
In Oracle/PLSQL, the to_date function converts a string to a date.

By Subhash Reddy Aedla Page 88 of 304


ORACLE

The syntax for the to_date function is:


to_date (string1, [format_mask], [nls_language] )

string1 is the string that will be converted to a date.


format_mask is optional. This is the format that will be used to convert string1 to a
date.
nls_language is optional. This is the nls language used to convert string1 to a date.
The following is a list of options for the format_mask parameter These parameters can
be used in many combinations.
Parameter Explanation

YEAR Year, spelled out

YYYY 4-digit year

YYY Last 3, 2, or 1 digit(s) of year.


YY
Y

IYY Last 3, 2, or 1 digit(s) of ISO year.


IY
I

IYYY 4-digit year based on the ISO standard

RRRR Accepts a 2-digit year and returns a 4-digit year.


A value between 0-49 will return a 20xx year.
A value between 50-99 will return a 19xx year.

Q Quarter of year (1, 2, 3, 4; JAN-MAR = 1).

MM Month (01-12; JAN = 01).

MON Abbreviated name of month.

MONTH Name of month, padded with blanks to length of 9 characters.

RM Roman numeral month (I-XII; JAN = I).

WW Week of year (1-53) where week 1 starts on the first day of the year and
continues to the seventh day of the year.

W Week of month (1-5) where week 1 starts on the first day of the month and ends
on the seventh.

IW Week of year (1-52 or 1-53) based on the ISO standard.

By Subhash Reddy Aedla Page 89 of 304


ORACLE

D Day of week (1-7).

DAY Name of day.

DD Day of month (1-31).

DDD Day of year (1-366).

DY Abbreviated name of day.

J Julian day; the number of days since January 1, 4712 BC.

HH Hour of day (1-12).

HH12 Hour of day (1-12).

HH24 Hour of day (0-23).

MI Minute (0-59).

SS Second (0-59).

SSSSS Seconds past midnight (0-86399).

FF Fractional seconds. Use a value from 1 to 9 after FF to indicate the number of


digits in the fractional seconds. For example, 'FF4'.

AM, A.M., PM, or Meridian indicator


P.M.

AD or A.D AD indicator

BC or B.C. BC indicator

TZD Daylight savings information. For example, 'PST'

TZH Time zone hour.

TZM Time zone minute.

TZR Time zone region.

Conversion functions
These functions convert value from one data type to another. They are broadly
classified as
To_char ( )

By Subhash Reddy Aedla Page 90 of 304


ORACLE

It converts date to a value of varchar2 data type in a form specified by date format fmt.
If fmt is neglected then it converts date to varchar2 in the default date format.
To_char (date, [fmt])
Select to_char (sysdate, ‘ddth “of” fm month yyyy’) from dual;
Ans: 27th of January 1999
In the above example, fill mode (fm) format mask is used to avoid blank padding of
characters and zero padding to numeric.
Select to_char (sysdate, ‘yyyy “years “mm “ months “dd “days” ’) from dual;
To_date ( )
It converts char or varchar type to date type its format is To_date (char, [fmt]).
Format model, fmt specifies the form of character.
Select to_date (‘January 27 1999’, ‘month-dd-yyyy’) from dual;
To_number ( )
This function allows the conversion of string containing numbers into the number data
type on which arithmetic operations can be performed. This is largely unnecessary as
oracle does an implicit conversion of numbers contained in a string.
Select to_number (‘100’) from dual;
Miscellaneous functions
Uid
This function returns the integer value corresponding to the user currently logged in.
Select uid from dual;
User
This function returns the login’s user name, which is varchar2 type.
Select user from dual;
Null value (NVL)
This function is used in cases where we want to consider Null values as zeros. The syntax
is
Nvl (expression 1, expression 2)
* if expression 1 is Null, nvl will return expression 2.
* if expression 1 is not Null, nvl will return expression 1.

By Subhash Reddy Aedla Page 91 of 304


ORACLE

* if expression 1 and 2 to the data type of expression 1 and then compares it.
Select empno, nvl (deptno, o) from emp;
Select empo, nvl (comm, o) from emp;
Null values and zeros are not equivalent. Null values are represented by blank and zeros
by (0).
Decode
Unlike the translate function which performs a character replacement the DECEDE
function does a value by value replacement.
Syntax
Select decode (<value, if1, then1, if2, then2, …. >) from <table _ name>;
Select decode (ename, ‘SCOTT’, ‘scotts’) from emp;
Select decode (rtrim (ename), ‘SCOTT’, ‘SUNIL’,’MILLER’, ‘MURALI’) from emp;
Vsize
This function returns the no of bytes in expression vsize.
Select vsize (‘hello’) from dual;

Group functions
Group functions returns a result based on a group of rows. Some of these are pure
mathematical functions.
Average (avg)
This function will return the average of values of the column specified in the argument
of the column.
Select avg (sal) from emp;
Minimum (min)
This function will give the least of all the values of the column present in the argument.
Select min (sal) from emp;
Maximum (max)
This function returns the maximum of all the values of the column present in the
argument.
Select max (sal) from emp;

By Subhash Reddy Aedla Page 92 of 304


ORACLE

Sum
This returns sum of all the values of the column present in the argument.
Select sum (sal) from emp;
Count
It is used to count no of rows. It takes three arguments.
Select count (empno) from emp;
Count(*)
This function counts all the rows inclusive of duplicates and Nulls.
Select count (*) from emp;
Count (column_name)
Select count (sal) from emp;
Count (distinct col_name)
Select count (distinct sal) from emp;
The above query eliminates duplicate and null values in the column and provide the
result.
Group by clause
Beyond the group functions, there are also two group clauses: “having” and “group by”.
These are parallel to the where and order by clauses except that they act on groups, not
on individual rows. These clauses can provide very powerful insights into your data.
If an SQL statement consists of ‘where’ clause and ‘group by’, than the latter should
follow the former.
Select dept, max (sal) from emp group by dept;
Select deptno, avg (sal) from emp group by dept;
Having clause
It is used to specify certain conditions on rows, retrieved by using ‘group by’ clause. This
clause should be preceded by a ‘group by’ clause.
Select dept, max (sal) from emp group by dept having dept not in 20;
Stddev (standard deviation)
Select deptno, stddev (sal) from emp group by deptno;
Varience

By Subhash Reddy Aedla Page 93 of 304


ORACLE

Select deptno, varience (sal) from emp group by deptno;

By Subhash Reddy Aedla Page 94 of 304


ORACLE

Working with Multiple Tables


Set operators
Set operators combine the results of two queries into a single one. The following set
operators aid SQL in joining queries to retrieve rows.
The columns in the select statements joined using the set operators should adhere
strictly to these rules.
The queries, which are related by a set operator should have the same number of
columns and the corresponding columns, must be of the same data type.
Such a query should not contain any column of long type.
The label under which the rows are displayed are those from the first select statement.
Union
The union operator returns all distinct rows selected by both queries.
Select empno from emp union
Select empno from myemp;
Select Sno from student union
Select Rno from students;
Union All
The “union all” operator returns all rows selected by either query including duplicates.
Select empno from emp union all
Select empno from myemp;
Intersect
The “Intersect” operator returns only rows that are common to both the queries.
Select empno, from emp intersect
Select empno from myemp;
Select deptno from emp intersect
Select deptno from dept;
Minus
The “minus” operator returns all distinct rows selected only by the first query and not
by the second.

By Subhash Reddy Aedla Page 95 of 304


ORACLE

Select deptno from dept minus


Select deptno from emp;

Joins
The purpose of a join is to combine the data spread across tables. A join is actually
performed by the ‘where’ clause which combines the specified rows of tables. For
combining data where a common column will provide the join condition the references
to the table names must be made to avoid ambiguity if a join involves over two tables
then oracle joins the first two based on the condition and then compares the result with
the next table and so on.
The syntax for joining tables is as follows:
Select columns from table1, table2 where logical expression;
The logical expression amounts to providing the join condition.
There are basically three different types of joins. They are
Simple join
Self join
Outer join
Simple Join
It is the most common type of join. It retrieves rows from two tables having a common
column and is further classified into
Equi join
A join which is based on equalities, is called an equi-join. The equi-join combines rows
that have equivalent values for a specified columns.
Select empno, ename, sal, dname, from emp, dept where emp.deptno = dept.deptno;
Non equi-join
It specifies the relationship between columns belonging to different tables by making
use of the relational operators, other then equal.
Select itemdesc, max_level, qty_ord, qty_deld from itemfile, order_detail, where
((itemfile.max_level<order_detail.qty_ord)anditemfile_itemcode=order_detail.itemcod
e);
Select empno, ename sal dname loc from emp, dept where emp.deptno>dept.deptno;
Table Aliases

By Subhash Reddy Aedla Page 96 of 304


ORACLE

Table aliases are used to make multiple table queries shorter and more readable. As a
result, we given an alias to the table in the ‘form’ clause. The aliases can be used instead
of the table name throughout the query.
Select e.empno, e.ename, e.sal, e.loc, d.dname from emp e, dept d where
e.deptno=d.deptno;
Self Join
Joining of a table to itself is known as a selfjoin i.e., it joins one row in a table to another.
The join is performed by mirroring the table using the ‘where’ clause, it can compare
each row of the table to itself and also with other rows of the same table.
Select e.empno, e.ename, e.job, e.sal, d.location from emp e, dept d where
e.deptno<d.deptno and e.job=’manager’ and e.hiredate!=’01-jan-82’;
Select e.empno, e.name, e.sal, e.hiredate, d.name, d.loc from emp e dept d where
e.deptno<d.deptno and e.job=’manager’ and e.hiredate <’01-jan-83’;
Outer Join
This extends the results of a simple join. An outer join returns all the rows returned by
simple join as well as those rows from one table that do not match any row from the
other table. The symbol (+) represents outer join.
Select empno, ename, sal, dname, location from emp, dept where
emp.deptno=dept.deptno(+);
The above query returns one record that does not matches with the above condition
from emp
Select e.empno, e.ename, e.job, d.dame, d.loc from emp e, dept d when
e.deptno(+)=d.deptno ;
The above query will return one separate record from dept table.

Sub Queries
Nesting of queries, one within the other is termed as a sub queries. A statement
containing a sub query is called as parent statement. Sub queries are used to retrieve
data from tables that depend on the values in the table itself.
The sub query features is less well known than SQL’s join features, but it plays an
important role in SQL for three reasons:
An SQL statement with a sub query is often the most natural way to express a query,
because it most closely parallels the English-Language description of the query.

By Subhash Reddy Aedla Page 97 of 304


ORACLE

Sub queries make it easier to write “select” statements, because they let you “break a
query down into pieces” and then “put the pieces together”.
There are some queries that cannot be expressed in SQL without using a sub query.
Example:
Select * from emp where deptno = (select deptno from dept where dname =’SALES’);
Select * from emp where deptno = (select deptno from dept where loc=’DALLAS’);
Sub queries that return several values:
Sub queries can also return more than one value. In such cases we should include
operator like “any, all, in or not in” between the comparison operator and the sub
query.
Select * from emp where sal < any (select sal from myemp where deptno between 10
and 30);
Note:
=any is equivalent to in
!=all is equivalent to not in.
Multiple sub queries:
Oracle places a no limit on the number of queries included in a where clause. It allows
nesting of query within a sub query. Doing so narrows down the area of search from
which the result is obtained.
Select empno, ename, sal, job from emp where deptno= (select deptno from dept
where loc=’chicago’) or deptno in (select deptno from emp e, dept d where
e.deptno=d.deptno);
Sub query within sub query:
Select * from emp where deptno=(select deptno from dept where deptno=(select
deptno from myemp where empno =1111 and ename=’AKHIL’));
Correlated sub query:
A sub query is evaluated once for the entire parent statement where as a correlated sub
query is evaluated once for every row processed by the parent statement.
Note:

By Subhash Reddy Aedla Page 98 of 304


ORACLE

If a sub query is selected from the same table as the main query, then the main query
must define an alias for the table name, and the sub query must use the alias to refer to
the column’s value in the main query.
Select * from emp x where sal > (select avg(sal) from emp y where x.deptno=y.deptno);
Select distinct (sal) from emp x where &n= (select count (dist (sal)) from emp y where
y.sal >= x.sal);
To delete only duplicate records
Delete from emp e where rowed not in (select min (rowed) from emp e1where
e.empno=e1.empno);
Exists /not exists operators:
The exists operator is a Boolean operator that evaluates to either true or false. This
operator takes a sub query as an argument. It evaluates to true if the sub query
produces some rows and false if no rows are fetched.
Select * from emp e where exists (select * from dept where deptno=e.deptno);
Select * from dept where not exists (select * from emp where
dept.deptno=emp.deptno);
Single row sub query
Here the inner query returns a single value to the outer query column then it is called
single row query
Select * from emp where sal = (select max (sal) from emp);
Using distinct in sub query
Select * from dept where deptno = (select distinct deptno from emp where
job=’MANAGER’);
Differences between sub query & correlated sub query:
Sub Query Correlated Sub Query
1. Inner query will be executed first. 1. Outer query will be executed first.
2. Inner query will be executed and it 2. For each & every row processed by
will assign that value to the outer outer query, the inner query will be
query then the outer query will be executed repeatedly.
executed. 3. There is a referencing outer query
3. Here there is no referencing outer column in inner query.

By Subhash Reddy Aedla Page 99 of 304


ORACLE

query column in inner query

By Subhash Reddy Aedla Page 100 of 304


ORACLE

Integrity Constraints
Constraints are declarations of conditions about the database that must remain true.
These include attributed-based, tuple-based, key, and referential integrity constraints.
The system checks for the violation of the constraints on actions that may cause a
violation, and aborts the action accordingly.
A constraint is a rule that the database manager enforces.
There are three types of constraints:
 A unique constraint is a rule that forbids duplicate values in one or more
columns within a table. Unique and primary keys are the supported unique
constraints. For example, a unique constraint could be defined on the supplier
identifier in the supplier table to ensure that the same supplier identifier is not
given to two suppliers.
 A referential constraint is a logical rule about values in one or more columns in
one or more tables. For example, a set of tables shares information about a
corporation's suppliers. Occasionally, a supplier's name changes. A referential
constraint could be defined stating that the ID of the supplier in a table must
match a supplier id in the supplier information. This constraint prevents inserts,
updates or deletes that would otherwise result in missing supplier information.
 A table check constraint sets restrictions on data added to a specific table. For
example, it could define the salary level for an employee to never be less than
$20,000.00 when salary data is added or updated in a table containing personnel
information.
A unique constraint is the rule that the values of a key are valid only if they are unique
within the table. Unique constraints are optional and can be defined in the CREATE
TABLE or ALTER TABLE statement using the PRIMARY KEY clause or the UNIQUE clause.
The columns specified in a unique constraint must be defined as NOT NULL. A unique
index is used by the database manager to enforce the uniqueness of the key during
changes to the columns of the unique constraint.
A table can have an arbitrary number of unique constraints, with at most one unique
constraint defined as a primary key. A table cannot have more than one unique
constraint on the same set of columns.

Unique Constraints
A unique constraint is the rule that the values of a key are valid only if they are unique
within the table. Unique constraints are optional and can be defined in the CREATE

By Subhash Reddy Aedla Page 101 of 304


ORACLE

TABLE or ALTER TABLE statement using the PRIMARY KEY clause or the UNIQUE clause.
The columns specified in a unique constraint must be defined as NOT NULL. A unique
index is used by the database manager to enforce the uniqueness of the key during
changes to the columns of the unique constraint.
A table can have an arbitrary number of unique constraints, with at most one unique
constraint defined as a primary key. A table cannot have more than one unique
constraint on the same set of columns.
A unique constraint that is referenced by the foreign key of a referential constraint is
called the parent key.

Referential Constraints
Referential integrity is the state of a database in which all values of all foreign keys are
valid. A foreign key is a column or set of columns in a table whose values are required to
match at least one primary key or unique key value of a row of its parent table. A
referential constraint is the rule that the values of the foreign key are valid only if:
 they appear as values of a parent key, or
 Some component of the foreign key is null.
The table containing the parent key is called the parent table of the referential
constraint, and the table containing the foreign key is said to be a dependent of that
table.

Referential constraints are optional and can be defined in CREATE TABLE statements
and ALTER TABLE statements. Referential constraints are enforced by the database
manager during the execution of INSERT, UPDATE, DELETE, ALTER TABLE ADD
CONSTRAINT, and SET INTEGRITY statements. The enforcement is effectively performed
at the completion of the statement.
Table Check Constraints
A table check constraint is a rule that specifies the values allowed in one or more
columns of every row of a table. They are optional and can be defined using the SQL
statements CREATE TABLE and ALTER TABLE. The specification of table check constraints
is a restricted form of a search condition. One of the restrictions is that a column name
in a table check constraint on table T must identify a column of T.
A table can have an arbitrary number of table check constraints. They are enforced
when:
 A row is inserted into the table

By Subhash Reddy Aedla Page 102 of 304


ORACLE

 A row of the table is updated.


A table check constraint is enforced by applying its search condition to each row that is
inserted or updated. An error occurs if the result of the search condition is false for any
row.

Triggers
A trigger defines a set of actions that are executed at, or triggered by, a delete, insert, or
update operation on a specified table. When such an SQL operation is executed, the
trigger is said to be activated.
Triggers can be used along with referential constraints and check constraints to enforce
data integrity rules. Triggers can also be used to cause updates to other tables,
automatically generate or transform values for inserted or updated rows, or invoke
functions to perform tasks such as issuing alerts.
Triggers are a useful mechanism to define and enforce transitional business rules which
are rules that involve different states of the data (for example, salary cannot be
increased by more than 10 percent). For rules that do not involve more than one state
of the data, check and referential integrity constraints should be considered.
Using triggers places the logic to enforce the business rules in the database and relieves
the applications using the tables from having to enforce it. Centralized logic enforced on
all the tables means easier maintenance, since no application program changes are
required when the logic changes.
Triggers are optional and are defined using the CREATE TRIGGER statement.
Examples

NOT NULL Constraints


The NOT NULL constraint specifies that a column cannot contain nulls. To satisfy this
constraint, every row in the table must contain a value for the column.
The NULL keyword indicates that a column can contain nulls. It does not actually define
an integrity constraint. If you do not specify either NOT NULL or NULL, the column can
contain nulls by default.
You can only specify NOT NULL or NULL with column_constraint syntax in a CREATE
TABLE or ALTER TABLE statement, not with table_constraint syntax.
Example
The following statement alters the EMP table and defines and enables a NOT NULL
constraint on the SAL column:

By Subhash Reddy Aedla Page 103 of 304


ORACLE

ALTER TABLE emp


MODIFY (sal NUMBER CONSTRAINT nn_sal NOT NULL);
NN_SAL ensures that no employee in the table has a null salary.

UNIQUE Constraints
The UNIQUE constraint designates a column or combination of columns as a unique key.
To satisfy a UNIQUE constraint, no two rows in the table can have the same value for
the unique key. However, the unique key made up of a single column can contain nulls.
A unique key column cannot be of datatype LONG or LONG RAW. You cannot designate
the same column or combination of columns as both a unique key and a primary key or
as both a unique key and a cluster key. However, you can designate the same column or
combination of columns as both a unique key and a foreign key.
Example
The following statement creates the DEPT table and defines and enables a unique key
on the DNAME column:
CREATE TABLE dept
(deptno NUMBER(2),
dname VARCHAR2(9) CONSTRAINT unq_dname UNIQUE,
loc VARCHAR2(10) );
The constraint UNQ_DNAME identifies the DNAME column as a unique key. This
constraint ensures that no two departments in the table have the same name. However,
the constraint does allow departments without names.
Defining Composite Unique Keys
A composite unique key is a unique key made up of a combination of columns. Since
Oracle creates an index on the columns of a unique key, a composite unique key can
contain a maximum of 16 columns. To define a composite unique key, you must use
table_constraint syntax, rather than column_constraint syntax.
To satisfy a constraint that designates a composite unique key, no two rows in the table
can have the same combination of values in the key columns. Also, any row that
contains nulls in all key columns automatically satisfies the constraint. However, two
rows that contain nulls for one or more key columns and the same combination of
values for the other key columns violate the constraint.

By Subhash Reddy Aedla Page 104 of 304


ORACLE

Example
The following statement defines and enables a composite unique key on the
combination of the CITY and STATE columns of the CENSUS table:
ALTER TABLE census
ADD CONSTRAINT unq_city_state
UNIQUE (city, state);
The UNQ_CITY_STATE constraint ensures that the same combination of CITY and STATE
values does not appear in the table more than once.

PRIMARY KEY Constraints


A PRIMARY KEY constraint designates a column or combination of columns as the table's
primary key. To satisfy a PRIMARY KEY constraint, both of the following conditions must
be true:
 No primary key value can appear in more than one row in the table.
 No column that is part of the primary key can contain a null.
 A table can have only one primary key.
Example
The following statement creates the DEPT table and defines and enables a primary key
on the DEPTNO column:
CREATE TABLE dept
(deptno NUMBER(2) CONSTRAINT pk_dept PRIMARY KEY,
dname VARCHAR2(9),
loc VARCHAR2(10) )

The PK_DEPT constraint identifies the DEPTNO column as the primary key of the
DEPTNO table. This constraint ensures that no two departments in the table have the
same department number and that no department number is NULL.
Alternatively, you can define and enable this constraint with table_constraint syntax:
CREATE TABLE dept
(deptno NUMBER(2),
dname VARCHAR2(9),
loc VARCHAR2(10),

By Subhash Reddy Aedla Page 105 of 304


ORACLE

CONSTRAINT pk_dept PRIMARY KEY (deptno) );


Defining Composite Primary Keys
A composite primary key is a primary key made up of a combination of columns.
Because Oracle creates an index on the columns of a primary key, a composite primary
key can contain a maximum of 16 columns. To define a composite primary key, you
must use the table_constraint syntax, rather than the column_constraint syntax.
Example
The following statement defines a composite primary key on the combination of the
SHIP_NO and CONTAINER_NO columns of the SHIP_CONT table:
ALTER TABLE ship_cont
ADD PRIMARY KEY (ship_no, container_no) DISABLE;
This constraint identifies the combination of the SHIP_NO and CONTAINER_NO columns
as the primary key of the SHIP_CONTAINER. The constraint ensures that no two rows in
the table have the same values for both the SHIP_NO column and the CONTAINER_NO
column.
The CONSTRAINT clause also specifies the following properties of the constraint:
Since the constraint definition does not include a constraint name, Oracle generates a
name for the constraint.
The DISABLE option causes Oracle to define the constraint but not enable it.

Referential Integrity Constraints


A referential integrity constraint designates a column or combination of columns as a
foreign key and establishes a relationship between that foreign key and a specified
primary or unique key, called the referenced key. In this relationship, the table
containing the foreign key is called the child table and the table containing the
referenced key is called the parent table. Note the following caveats:
 The child and parent tables must be on the same database.
 The foreign key and the referenced key can be in the same table. In this case, the
parent and child tables are the same.
To satisfy a referential integrity constraint, each row of the child table must meet one of
the following conditions:
 The value of the row's foreign key must appear as a referenced key value in one
of the parent table's rows. The row in the child table is said to depend on the
referenced key in the parent table.

By Subhash Reddy Aedla Page 106 of 304


ORACLE

 The value of one of the columns that makes up the foreign key must be null.
Example
The following statement creates the EMP table and defines and enables a foreign key on
the DEPTNO column that references the primary key on the DEPTNO column of the
DEPT table:
CREATE TABLE emp
(empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9),
mgr NUMBER(4), hiredate DATE, sal NUMBER(7,2),
comm NUMBER(7,2), deptno NUMBER(2) CONSTRAINT fk_deptno REFERENCES
dept(deptno) );
The constraint FK_DEPTNO ensures that all departments given for employees in the
EMP table are present in the DEPT table. However, employees can have null department
numbers, meaning they are not assigned to any department. If you wished to prevent
the latter, you could create a NOT NULL constraint on the deptno column in the EMP
table, in addition to the REFERENCES constraint.
Before you define and enable this constraint, you must define and enable a constraint
that designates the DEPTNO column of the DEPT table as a primary or unique key.
Note that the referential integrity constraint definition does not use the FOREIGN KEY
keyword to identify the columns that make up the foreign key. Because the constraint is
defined with a column constraint clause on the DEPTNO column, the foreign key is
automatically on the DEPTNO column.
Note that the constraint definition identifies both the parent table and the columns of
the referenced key. Because the referenced key is the parent table's primary key, the
referenced key column names are optional.
Note that the above statement omits the DEPTNO column's datatype. Because this
column is a foreign key, Oracle automatically assigns it the datatype of the
DEPT.DEPTNO column to which the foreign key refers.
Alternatively, you can define a referential integrity constraint with table_constraint
syntax:
CREATE TABLE emp
(empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9),
mgr NUMBER(4), hiredate DATE, sal NUMBER(7,2),
comm NUMBER(7,2), deptno NUMBER(2) CONSTRAINT fk_deptno
FOREIGN KEY (deptno) REFERENCES dept(deptno) );

By Subhash Reddy Aedla Page 107 of 304


ORACLE

Note that the foreign key definitions in both of the above statements omit the ON
DELETE CASCADE option, causing Oracle to forbid the deletion of a department if any
employee works in that department.
Specifying Referential Actions for Foreign Keys
Oracle allows different types of referential integrity actions to be enforced, as specified
with the definition of a FOREIGN KEY constraint:
The UPDATE/DELETE No Action Restriction This action prevents the update or deletion
of a parent key if there is a row in the child table that references
the key. By default, all FOREIGN KEY constraints enforce the no action restriction; no
option needs to be specified when defining the constraint to enforce the
no action restriction. For example:
CREATE TABLE Emp_tab ( FOREIGN KEY (Deptno) REFERENCES Dept_tab);
The ON DELETE CASCADE Action This action allows data that references the parent key
to be deleted (but not updated). If referenced data in the
parent key is deleted, all rows in the child table that depend on the deleted parent key
values are also deleted. To specify this referential action, include the ON
DELETE CASCADE option in the definition of the FOREIGN KEY constraint. For example:
CREATE TABLE Emp_tab ( FOREIGN KEY (Deptno) REFERENCES Dept_tab
ON DELETE CASCADE);
The ON DELETE SET NULL Action This action allows data that references the parent key
to be deleted (but not updated). If referenced data in the
parent key is deleted, all rows in the child table that depend on the deleted parent key
values have their foreign keys set to null. To specify this referential
action, include the ON DELETE SET NULL option in the definition of the FOREIGN KEY
constraint. For example:
CREATE TABLE Emp_tab ( FOREIGN KEY (Deptno) REFERENCES Dept_tab
ON DELETE SET NULL);
Enabling FOREIGN KEY Integrity Constraints
FOREIGN KEY integrity constraints cannot be enabled if the referenced primary or
unique key's constraint is not present or not enabled.

By Subhash Reddy Aedla Page 108 of 304


ORACLE

Locks and Table Partitions


Locks are mechanism used to prevent destructive interaction between users assessing
the same resources simultaneously. A resource can either be an entire table or a specific
row in a table. The locks provide a high degree of data concurrency. Locks can be
acquired at two different levels.
Row Level Locks
A row is locked exclusively so that other users cannot modify the row until the
transaction holding the lock is committed or roll backed. Row locks are acquired
automatically by oracle as a result of insert, update, delete and select, for update clause
statement.
Select * from emp where empno=7788 for update of sal, comm.;
Table Level Lock
A table level lock will protect table data there by guaranteeing data integrity when data
is being accessed concurrently by multiple users. A lock can be held in several modes,
they are.
Share Lock
Share Update Lock
Exclusive Lock
Syntax
Lock table <table_name> in <share or share update or exclusive mode>;
Share Lock
It Locks table allowing other users to only query but not insert, update or delete rows in
a table multiple users can place share Locks on the same table at the same, i.e., it allows
resources to be shared, and hence the name share lock.
Lock table <table_name> in share mode;
Lock table emp in share mode;
Share Update Lock
It locks rows that are to be updated in a table. It permits other users to concurrently
query, insert update or even lock rows in the same table. It prevents the other users
from updating the row that has been locked. We can enforce a share update lock by
using for update clause in select statement.

By Subhash Reddy Aedla Page 109 of 304


ORACLE

Lock table itemfile in share update mode;


Although a share update lock falls under table level category. It is effective only for
rows.
It allows numerous users to concurrently lock different rows of a table.
Exclusive Lock
It is the most restrictive of table locks. When issued by one user it allows the other users
to only query but not insert, delete, or update rows in a table. It is almost similar to a
share lock but only one user can place an exclusive lock on a table at a time.
Lock table itemfile in exclusive mode;
Nowait
Lock table itemfile in exclusive mode nowait;
If a user locked a table without ‘nowait’ clause and if other user tries to violate the
above restrictions by trying to lock the table then he will be made to wait indefinitely
until the user who has initially locked the table issues commit or rollback statement.
This delay could be avoided by appending ‘nowait’ clause in the lock table command.
Dead lock
It occurs when two users have a lock, each on a separate object, and they wants to
acquire a lock on the each other object. When this happens, first user has to wait for the
second user to release the lock, but the second user will not release it until the lock on
the first user’s object is freed. At this point, both the users are at an impress and cannot
proceed with their business. In such a case oracle detects the dead lock automatically
and solves the problem by aborting one of the two transactions.

Partitioning
Partitioning addresses the key problem of supporting very large tables and indexes by
allowing you to decompose them into smaller and more manageable pieces called
partitions. Once partitions are defined, SQL statements can access and manipulate the
partitions rather than entire tables or indexes. Partitions are especially useful in data
warehouse applications, which commonly store and analyze large amounts of historical
data.
Partitioning Methods
Two primary methods of partitioning are available: range partitioning, which partitions
the data in a table or index according to a range of values, and hash partitioning, which
partitions the data according to a hash function. Another method, composite

By Subhash Reddy Aedla Page 110 of 304


ORACLE

partitioning, partitions the data by range and further subdivides the data into
subpartitions using a hash function.
Range Partitioning
Range partitioning maps rows to partitions based on ranges of column values. Range
partitioning is defined by the partitioning specification for a table or index:
PARTITION BY RANGE ( column_list )
and by the partitioning specifications for each individual partition:
VALUES LESS THAN ( value_list )
where:
 column_list is an ordered list of columns that determines the partition to which a
row or an index entry belongs. These columns are called the partitioning
columns. The values in the partitioning columns of a particular row constitute
that row's partitioning key.
 value_list is an ordered list of values for the columns in column_list. Each value
in value_list must be either a literal or a TO_DATE() or RPAD() function with
constant arguments. The value_list contained in the partitioning specification for
each partition defines an open (noninclusive) upper bound for the partition,
referred to as the partition bound. The partition bound for each partition must
compare less than the partition bound for the next partition.
For example, in the following table of four partitions (one for each quarter's sales), a
row with SALE_YEAR=1997, SALE_MONTH=7, and SALE_DAY=18 has partitioning key
(1997, 7, 18). Therefore it belongs in the third partition and is stored in tablespace TSC.
A row with SALE_YEAR=1997, SALE_MONTH=7, and SALE_DAY=1 has partitioning key
(1997, 7, 1) and also belongs in the third partition, stored in tablespace TSC.
CREATE TABLE sales
( invoice_no NUMBER, sale_year INT NOT NULL, sale_month INT NOT NULL,
sale_day INT NOT NULL )
PARTITION BY RANGE (sale_year, sale_month, sale_day)
( PARTITION sales_q1 VALUES LESS THAN (1997, 04, 01)
TABLESPACE tsa,
PARTITION sales_q2 VALUES LESS THAN (1997, 07, 01)
TABLESPACE tsb,
PARTITION sales_q3 VALUES LESS THAN (1997, 10, 01)
TABLESPACE tsc,
PARTITION sales_q4 VALUES LESS THAN (1998, 01, 01)

By Subhash Reddy Aedla Page 111 of 304


ORACLE

TABLESPACE tsd );
Hash Partitioning
Although partitioning by range is well-suited for historical databases, it may not be the
best choice for other purposes. Another method of partitioning, hash partitioning, uses
a hash function on the partitioning columns to stripe data into partitions. Hash
partitioning allows data that does not lend itself to range partitioning to be easily
partitioned for performance reasons such as parallel DML.
Hash partitioning is a better choice than range partitioning when:
 You do not know beforehand how much data will map into a given range
 Sizes of range partitions would differ quite substantially
The following example creates a table that names and stores a hash partition in a
specific tablespace:
CREATE TABLE product( ... ) STORAGE (INITIAL 10M) PARTITION BY HASH(column_list)
( PARTITION p1 TABLESPACE h1, PARTITION p2 TABLESPACE h2 );
Composite Partitioning
Composite partitioning partitions data using the range method and, within each
partition, subpartitions it using the hash method. This type of partitioning supports
historical operations data at the partition level and parallelism (parallel DML) and data
placement at the subpartition level.
CREATE TABLE orders(
ordid NUMBER,
orderdate DATE,
productid NUMBER,
quantity NUMBER)
PARTITION BY RANGE(orderdate)
SUBPARTITION BY HASH(productid) SUBPARTITIONS 8
STORE IN(ts1,ts2,ts3,ts4,ts5,ts6,ts7,ts8)
( PARTITION q1 VALUES LESS THAN('01-APR-1998'),
PARTITION q2 VALUES LESS THAN('01-JUL-1998'),
PARTITION q3 VALUES LESS THAN('01-OCT-1998'),
PARTITION q4 VALUES LESS THAN(MAXVALUE));
In this example, the ORDERS table is range partitioned on the ORDERDATE key, in four
separate ranges representing quarters of the year. Each range partition is further

By Subhash Reddy Aedla Page 112 of 304


ORACLE

subpartitioned on the PRODUCTID key into eight subpartitions, for a total of 32


subpartitions. Each tablespace contains one subpartition from each partition.

Table Partitions
Dividing the rows of a single table into multiple parts is called partitioning the table, the
table that is partitioned is called a partitioned table and the parts are called partitions.
Although the partitions are held and managed independently they can be queried and
updated by reference to the name of the logical table.
There is a difference between a table, which has a single partition and a table that has
no partitions. A non-partitioned table cannot be partitioned later. Each partition is
stored in different table spaces. Oracle 9i also provides partition independence. We can
access and manipulate data in one partition even if some or all of the other partitions
are unavailable. This is a major benefit to administrators and users alike.
Storing the partitions in different table spaces has its advantages:
1. It reduces the possibility of data corruption in multiple partitions.
2. Backup and recovery of each partition can be done independently.
3. Controlling the mapping of partitions to disk drives (important for balancing I/O
load) is possible.
Partitioned tables cannot contain any columns with long or long raw data types, LOB
data types (BLOB, CLOB, NCLOB or BFILE), or object types.
Partitioning is useful for very large tables. By splitting a large table rows across multiple
smaller partitions, you accomplish several important goals.
1. The performance of queries against the tables may improve, since oracle may
have to only search one partition instead of the entire table to resolve a query.
2. The table may be easier to manage, since the partitioned tables’ data is stored in
multiple parts, it may be easier to load and delete data in the partitions than in
the large table.
3. Backup and recovery operations may perform better, since the partitions are
smaller than the partitioned table, you may have more options for backing up
and recovering the partitions then you would have for a single large table.
Advantages of Table Partitions
There are two primary reasons for partitioning a table (1) Disk Space and (2) Processing
Time.

By Subhash Reddy Aedla Page 113 of 304


ORACLE

Partitions can be altered, dropped, rebuilt, merged and truncated. Partitions cannot
have synonyms.
Syntax
Create table <table_name>(column1, column2) partition by range (column_name)
(partition <partition_name> values less than <value>, partition <partition_name> values
less then <value>);
Create table emp_d (no number(4), ename varchar2(10), post varchar2(10), salary
number(8,2), deptno number(2)) partition by range (no) (partition p1 values less than
(20), partition p2 values less than (40));
Select * from emp_d partition (p1);
Select * from emp_d partition (p2);
A table can also be partitioned on more than one column. The partition key specified in
the insert statement is compared with partition bound defined when creating the
partition table.
Create table ordmast (ordno number(3) constraint ok primary key, ordate date, vcode
varchar2(8), deldate date) partition by range (ordno, vcode) (partition p1 values less
than (10,’v10’), partition p2 values less than (20,’v20’), partiion p3 values less than
(maxvalues, maxvalues));
The key word ‘maxvalues’ can be specified for any value in the partition bound value list.
This keyword represents a virtual ‘infinite’ value that sorts higher than any other value
for the data type, including the null values.
The table partitions can be also placed in table spaces defined by the user as per his
discretion through this optional.
Syntax
Create table <table_name> (c1, c2) partition by range (c_name) (partition <p_name>
values less than <value> tablespace <tablespace_name>, partition <p_name> values less
than <value> tablespace <tablespace_name>);
Adding Partition
It is used to add a new partition after the existing last partition (referred to as the high
end).
Alter table emp_d add partition p3 values less than (30);
 The add partition option shown above is only for tables where the last existing
partition has been defined with a specific key value.

By Subhash Reddy Aedla Page 114 of 304


ORACLE

 If we wish to add a partition at the beginning or in the middle of a table, or if the


partition bound on the highest partition is maxvalue, we should use the split
partition statement.
Select partition_name, tablespace_name, table_name from user_tab_partitions;
Dropping Partitions
To drop partitions the drop partition clause can be made use of alter table statement.
Alter table emp_d drop partition p3;
Splitting Partitions
It is used to split a partition into two. This is useful when partition becomes too large
and causes backup, recovery or maintenance operations to consume a lot of long time.
Alter table emp_d split partition p3 at (25) into (partition p21, partition p22);
Exchanging Table Partitions
Exchanging table partitions is used to convert a partition into a non-partitioned table,
and a table into a partition of a partitioned table by exchanging their data segments.
Exchanging table partitions is most useful when an application using non-partitioned
tables need to be converted into partitions of a partitioned table.
Create table emp_d(no number(3), name varchar2(10), salary number(8,2)) partition by
range (no) (partition p1 values less than (10), partition p2 less than (20), partition p3
values less than (maxvalue));
Now create a table temp with same structure as emp_d and insert values into it.
Create table temp (no number(3), name varchar2(10), salary number(8,2));
Select * from emp_d partition p1;
Select * from emp_d partition p2;
Select * from emp_d partition p3;
Select * from temp;
The following command will exchange the data between the partition p2 and the table
temp.
Alter table emp_d exchange partition p2 with table temp;
Select * from temp;
Select * from emp_d partition p2;

By Subhash Reddy Aedla Page 115 of 304


ORACLE

Database Objects
Synonyms
A synonym is a database object, which is used as an alias (alternative name) for a table,
view or sequence.
The main reasons for creating synonyms are:
1. Simplify SQL statements
2. The true name of the owner or table needs to be hidden.
3. The original location of the table needs to be hidden, for remote objects of a
distributed database.
4. Provide public access to an object.
Synonyms can be either public or private. A private synonym can be created by normal
user, which is available only to that person where as a public synonyms are created by
DBA, which can be availed by any database user.
Syntax
Create [public] synonym <syn_name> for table_name>;
Create synonym emp_sy for emp;
Grant all on emp_sy to <user_name>;
The user who has permission on a synonym can do all DML manipulations such as insert,
delete, update on the synonym, but he cannot perform any DDL operations on synonym
actually affect table.
TAB is the public synonym created by DBA.
If we have public & private objects with the same name, the private objects take
precedence.
Create table tab (a number);
Select * from tab;
No rows

Sequences
Sequences are numeric column values that are computer generated. A sequence is a
database object, which can generate unique, sequential integer values. It can be used to

By Subhash Reddy Aedla Page 116 of 304


ORACLE

automatically generate primary or unique key values. A sequence can be either in an


ascending or in descending order.
Syntax
Create sequence <seq_name> increment by n [start with n][max value n][min value n]
[cycle/no cycle][cache/no cache];
Increment by n: specifies the interval between two numbers.
Start with n: first number to be generated.
Min value n: specifies the minimum value of the sequence. By default 1 for ascending
sequence and 10e26-1 for descending sequence.
Max value n: specifies the maximum value of the sequence, -1 for descending and
10e27-1 for ascending.
Cycle: continues to generate sequence even after reaching max value.
No cycle: stops once it reaches max value, by default no cycle.
Cache: retains previous numbers in the memory, default no cache.
Example
Create sequence s1 increment by 1 start with 1 max value 10 min value 1 cycle cache 5;
After creating sequence we can access its values with the help of pseudo columns like
currval & nextval.
A pseudo column behaves like a table column, but it is not actually stored in the table.
We can select values from pseudo columns but cannot perform manipulations on their
values.
Nextval: it returns initial value of the sequence, when referred to for the first time and
then the incremented values.
Currval: returns current value of the sequence.
Insert into emp_d (no,name) values (s1.nextval,’ankit’);
Select s1.currval from dual;
Alter sequence
A sequence can be altered when we want to perform the following.
1. Set or eliminate min or max values.
2. Change the increment value.

By Subhash Reddy Aedla Page 117 of 304


ORACLE

3. Change the number of cached sequence numbers


Alter sequence s1 maxvalue 50;
Drop sequence s1;

Views
A view is a SQL query that is permanently stored in database and assigned a name. it is a
tailored presentation of data contained in one or more tables. A view takes the output
of a query and treats it as a table; therefore a view can be thought of as a “stored
query” or a “virtual table”. Using SQL, you can create alternative views of the
information in your tables. Views let you restrict access to data, allowing different users
to see only certain rows or certain columns of a table.
Advantages of Views
Security
Each user can be given permission to access the database only through a small set of
views that contain the specific data the user is authorized to see, thus restricting the
users access to stored data.
Query Simplicity
A view can draw data from several different tables and present it as a single table,
turning multi-table queries into single-table queries against view.
Structural Simplicity
Views can give a user a “personalized” view of the database structure, presenting the
database as set of virtual tables that make sense for the user.
Insulation from Change
A view can present a consistent unchanged image of the structure of the database, even
if the underling source tables are split, restructured or renamed.
Data Integrity
If data is accessed and entered through a view the DBMS can automatically check the
data to ensure that it meets specified integrity constraints.
Syntax
Create *or replace+ **no+ *force++ view <view_name> *column alias name….+ as <query>
[with [check option] [read only] [constraint]];
Create view v1 as select * from emp_d;

By Subhash Reddy Aedla Page 118 of 304


ORACLE

Create view v2 as select * from emp_d where deptno=10;


Grant all on v2 to <user_name>;
Updating View
The ANSI/ISO SQL standard specifies the views that must be updateable in a db that
claims conference to the standard.
A view can be updated if the query that defines the view meets all of the following
restrictions.
1. The FROM clause must specify only one table (updateable) i.e., the view must
have a single source table for which the user has the required privileges. If the
source table is itself a view, then that view must meet there criteria.
2. DISTINCT must not be specified, i.e., duplicate rows must not be eliminated from
the query results.
3. Each select item must be a simple column reference; the select list cannot
contain expressions calculated columns, or column functions.
4. The WHERE clause must not include a sub-query, only simple row-by-row search
conditions may appear.
5. The query must not include a GROUP BY or a HAVING clause.
Update view v2 set name=’Ankit’ where name=’Akhil’;
View with read only option
Create or replace view v1 as select * from emp with read only;
The above command will create a view which is read only. No other operation other
than select is allowed on this table. Any other operators will raises and error.
Creating view with errors
If there are no syntax errors in a create view statement, oracle will create the view even
if the view defining query refers to a non-existent table or even an invalid column of an
existing table or when the view will be created anyway and entered into the data
dictionary. However, the view is not yet usable. The view is considered ‘created with
errors’.
Create force view vi as select * from table temp;
Here table temp does not exist; still view is created with errors. If now we create table
temp, the view is recompiled and becomes a valid view.
Alter view vi compile;

By Subhash Reddy Aedla Page 119 of 304


ORACLE

DML statements and join view


Joining of tables is also possible in a view. Any UPDATE, INSERT, or DELETE statement on
a join view can modify only one underlying base table. But it is possible through instead
of triggers
Create view v1 as select empno,ename,job,sal,dname,loc from emp, dept where
emp.empno=dept.deptno;
USER_UPDATABLE-COLUMNS will help in identifying the updatable columns of a join
view.
Functions in View
Single row functions comprising of number, character, date, group functions and
expressions can also be used in views.
Create view v1 as select sum(sal) from emp group by deptno;
Create or replace view v1 as select avg(sal) average from emp group by deptno;
Partition View
With partition views, the database resides in separate tables. These tables are then
brought together at runtime using the relational operator “Union all”
Create view <view_name> as select * from <table_name1> union all select * from
<table_name>2 union all select * from <table_name3>;
Create view v1 as select * from emp union all select * from emp1 union all select * from
emp2 union all select * from emp3;
Drop view <view_name>;
Drop view v1;
Rename my_view1 to my_view2;

Index
Indexes are used to explicitly speed up SQL statement execution on a table, an oracle
index provides a faster access path to table data. The index points directly to the
location of the rows containing the values. Indexes are primary means of reducing disk
I/O when properly used.
We can create an index on a column or combinations of columns using “create index”
command. When e create index, oracle fetches and sorts the columns to be indexed
And sorts the rowed along with the index value of each row. Then oracle loads index
from bottom up.

By Subhash Reddy Aedla Page 120 of 304


ORACLE

Indexes are logically and physically independent of the data in the associated table. We
can create or drop index at any time without affecting the base tables or other indexes.
Oracle automatically maintains and uses indexes once they are created. Oracle
automatically reflects changes to data, such as addition of new rows, updating rows, or
deleting rows, in all relevant indexes with no additional action by users.
Unique Indexes
Indexes can be unique or non-unique. Unique indexes guarantee that no two rows of a
table have duplicate values in the columns that define index. Non-unique indexes do not
impose this restriction on the column values. Oracle enforces unique integrity
constraints by automatically defining a unique index on a unique key. A unique index is
created by using create unique index command.
Create unique index ind on emp (empno);
A unique index I automatically created when we create unique or primary key
constraint.
We cannot create index for a column which is already indexed and unique index o
columns with duplicate values.
Composite Index (Concatenated Index)
It is created on multiple columns of a table. Columns in a composite index ca appear in
any order and need not be adjacent columns o the table.
These indexes enhance the retrieval sped of data for select statements in which the
‘where’ clause references all or the leading portion of the columns in the composite
index. The most commonly accessed or most selective columns go first in the order of
the column list.
Create index ind1 on emp (empno, deptno);
The above created index is used to retrieve data, when the where clause has either both
of these column or empno alone but not deptno alone can be used.
Reverse Key Index
It reverses each byte of the column being indexed while keeping the column order. Such
an arrangement can help avoiding performance degradation in indexes when
modifications to the index are concentrated on a small set of blocks. By reversing the
keys of the index, the insertion become distributed all over the index.
Create index rind on emp (empno) reverse;
Alter index rind rebuild noreverse;

By Subhash Reddy Aedla Page 121 of 304


ORACLE

Clusters
Clusters are an optional method of storing table data. A cluster is a group of tables that
share the same data blocks because they share common columns and are often used
together. Clusters are special configurations to use when two or more tables are stored
in close physical proximity to improve performance on SQL join statements using those
tables.
Cluster is a method of storing tables that are intimately related and often joined
together into the same area on the disk. For example instead of EMP table being in one
section of the disk and the dept table being somewhere else, their rows could be
interleaved together in a single area, called a cluster. Clusters do not change the data
that is stored in tables, however, they do change the way that data is stored and
accessed. Oracle physically stores all rows for each department from both EMP and
DEPT tables in the same data blocks. To cluster tables, you must own the tables you are
going to cluster together.
The cluster key
The cluster key is the column, or group of columns, that are the clustered tables have in
common, for example deptno in emp and dept tables. You specify the columns of the
cluster ken when creating the cluster. You subsequently specify the same columns when
creating every table added to the cluster.
The cluster name follows the table naming conventions, and column datatype is the
name and datatype you will use as the cluster key. The column name may be same as
one of the columns of a table or it may be any other valid name.
Syntax for creating cluster command:
Create cluster clustername(column datatype *,column datatype+….)*other options+;
Example
Create Cluster Emp_Dept(Deptno_Key Number(2));
Create Table Dept1(Deptno Number(2)
Primary Key, Dname Varchar2(10)) Cluster Emp_Dept(Deptno);
Create Table Emp1(Empno Number(4) Primary Key,
Ename Varchar2(10), Job Varchar2(10),Sal Number(7,2),
Deptno Number(2) References Dept1(Deptno)) Cluster Emp_Dept(Deptno);

By Subhash Reddy Aedla Page 122 of 304


ORACLE

Insert Into Dept1 Values (&Dno,'&Dname');


Insert Into Emp1 Values(&Empno,'&Ename','&Job',&Sal,&Deptno);
Create Index Ind1 On Cluster Emp_Dept;

By Subhash Reddy Aedla Page 123 of 304


ORACLE

OOP Concepts in Oracle


ORDBMS Vs RDBMS
Relational systems are slower than traditional systems. However the risk that is involved
in a relational system is much less than the risk involved in a traditional system.
Developing applications in a relational system is much faster than developing them in a
traditional system. The traditional system involves writing the code, compiling it, linking
and testing it. This is inherently slower than a relational system in which changing and
implementation can be done much faster. Relations are easy to understand.
Understanding tables, rows and columns is simple. Understanding a relationship
between two tables is easy. Analyzing the relationship between various elements is also
very simple.
Concepts of Object Oriented Programming
Object-oriented programming is a way to organize data and code within the program.
While speaking about object oriented programming we need to know about a class,
object, attribute and methods.
Objects
An object is a reusable application component that developers need to be aware of,
rather than how it works. Objects are the basic entities in a system. They could
represent a person, place, bank account, or any item that is handled by the program.
Every object consists of an attribute and one or more methods. An attribute could be
any property of the object.
Class
Class refers to the definition of an object. Class helps in making the entire set of data
and code into a single user defined data type. Once the class has been defined, a
number of objects that belong to the same class can be created.
Attributes
Every object consists of methods and attributes. Attributes help in identifying an object.
Examples include name, phone number, department number etc.
Methods
Methods are functions and procedures that are used to perform actions related to the
object. Anything that is to be done with the object is implemented as a method.
Features of Object-Oriented Programming

By Subhash Reddy Aedla Page 124 of 304


ORACLE

The three main features of object oriented programming include:


 Encapsulation .
 Inheritance
 Polymorphism
Encapsulation
The wrapping of data and functions into a single unit is known as Encapsulation. Data is
not accessible externally and is accessible to only those functions, which are wrapped in
the class, can access it. These functions provide the interface between the data and
program. Encapsulation of data from direct access by the program is called 'Data
Hiding'.
Inheritance
Inheritance allows designing of new objects that inherit the functionality of objects that
are already created. This is a process by which objects of one class acquire the
properties of objects of another class. Inheritance provides the idea of reusability.
Polymorphism
The ability of an object to take more than one form is known as polymorphism. It
enables different objects to have methods of the same name that accomplish similar
tasks, but in different ways.

Object in Oracle
Oracle supports different types of objects. The major object types include:
 Abstract data types
 Varying arrays
 Nested Tables

Abstract Data types


Abstract data types are data types that consist of one or more subtypes. These are not
constrained to the standard Oracle data types.
An abstract datatype column includes:

Column Name Data Type


Street_no Number(3)

By Subhash Reddy Aedla Page 125 of 304


ORACLE

Street_name Varchar2(20)
City Varchar2(20)
State Varchat2(20)
When a table that uses the address information is created, a column that uses the
abstract data type for addresses could be used. The creation of the abstract data type
for address of an employee can be done at the SQL prompt. The code is as given below:
SQL> create or replace type address_ty as object (street_no number(3), street_name
varchar2(20), city varchar2(20), state varchar2(20));

The create type command is the most important command in Object-Relational


Database. This will create an abstract data type named as address_ty. The as object
clause explicitly identifies address_ty as an object oriented implementation. The replace
clause recreates the type if it already exists. This clause can be used to change the
definition of an existing type without dropping it.
Once an abstract data type has been created it can be used within other data types. The
abstract data type that has been created can be used to represent a column in a table.
Implementing an object type as a column object
Let us use the abstract data type to create a table and thereby insert values into it.
Use the abstract data type that is already given i.e., address_ty. Create a table named
vend_mast as shown below:
SQL> create table vend_mast (vencode varcbar2(5) , venname varcbar2(15) , venadd
address_ty, tel_no number(6));

Inserting Records into Abstract Data types


When abstract data types are created, Oracle creates method, called constructor
methods, for data management. A constructor method is a program that is named after
the data type. Its parameters are the names of the attributes defined for the data type.
When values are to be inserted into a table that is based on abstract data types, the
constructors have to be used.
SQL> insert into vend_mast values ('vlOO', 'charu',address_ty(llO, 'first st','chennai',
'tn'),465987);

Selecting from Abstract Data types


SQL> select * from vend_st;
SQL> select a.venadd.city from vend_st a,

By Subhash Reddy Aedla Page 126 of 304


ORACLE

With abstract data type inserting or selecting values cannot be done without knowing
the exact data type of attributes.
Updating Records in abstract data types
Updating is done in a similar manner to that of the select statement. The dot notation
and an alias of the table are used.
SQL> update vend_st a set a.venadd.street_no=10 where venname .. 'charu' ,

Deleting Record from abstract data types


To delete records that contain abstract data types use the dot notation and the table
alias. This is similar to updating and selecting values from rows abstract data types.
SQL> delete from vend_mast a where a.venadd.city = 'chennai';

Varying Arrays
Varray helps in storing repeating attributes of a record in a single row. Varying arrays
have a fixed lower value i.e., 0 and a flexible upper value i.e., could be any valid number.
Varray cannot be extended beyond the limit that was defined when the Varray was
created.
Collectors such as varying arrays allow repetition of only those column values that
change, potentially saving storage space. Collectors can be used to accurately represent
relationships between data types in the database objects.
Creating a Varying Array
A varying array can be based on an abstract data type or on one of Oracle's standard
data types. Assuming that ordecdetails table structure is known, a single ordemo
column could contain many itemcodes.
SQL> create type itemcode as varray(5) of varchar2(5);

The command given above creates a varying array that could contain a maximum of 5
values and each value could be of data type varchar2. The upper limit has to be
specifIed otherwise an error is raised by Oracle.
Let us create two other types called qty_ord and qty_deld so that these could be used in
the creation of a table.
SOL> create type qty_ord as varray(5) of number(5);

The example given above creates a varying array, which could contain a maximum of 5
values and each of these values could be of number data type.
SOL> create type qty_deld as varray(5) of number(5);

By Subhash Reddy Aedla Page 127 of 304


ORACLE

The example given above creates a varying array, which could contain a maximum of 5
values and each of these values could be of number data type. The varying arrays have
been created and a table can now be created using these arrays.
SOL> create table order_detail ( orderno varchar2(5), item_va it_code, qty_va qty_ord,
qtyd_va qty_deld);

Inserting Records into Varying Arrays


When a data type is created the database automatically creates a method called a
constructor method for the data type. The constructor method should be used while
inserting records into columns that use abstract data types. A varying array is also an
abstract data type. Hence constructor methods have to be used while inserting values
into them.
SQL>insert into order_detail values ('olOO',itemcode('il00','il0l',
'il02','i013','il04'),qty_ord(100,98,49,39,20), qty_deld(100,900,800,700,600»;

When values are inserted into the varying arrays care should be taken such that the
maximum limit is not exceeded. The maximum number is specified at the time of
creation of the array and can be queried using the user_col_types data dictionary view.
Selecting Data from Varying Arrays
SQL> select * from order_detail,

Selecting data from varray using collection unnesting


Collection column can be queried in a normal relational form using the TABLE
expression. In order to view collection data in a normal relational form, the collection
attribute of a row has to be unnested or flattened into one or more relational rows.
SQL> SELECT * FROM TABLE (SELECT t.item_va FROM order_detail t WHERE t.orderno . '0100');

Nested Tables
Varying arrays are used to create collectors within the table. Varying arrays have a
limited number of entries, whereas nested tables have no limit on the number of entries
per row. A nested table is a table within a table. A table is represented as a column
within another table. Multiple rows can be present in the nested table for each row in
the main table.
Creating Nested Tables
Let us assume that the table contains a structure as shown below:

Column Name Data Type

By Subhash Reddy Aedla Page 128 of 304


ORACLE

Orderno Varchar2(5)
Odate Date
Vencode Varchar2(5)
Itemcode Varchar2(2)
Qty_ord Number(5)
Qty_deld Number(5)

There are a number of itemcode for each ordemo. Each itemcode could contain a
unique qty _ord, qty _deld. The exact number of itemcode is not known and hence let
us create a type that is based on itemcode, qty _ord and qty _deld.
SQL> create type ord_ty as object (itemcode varchar2(5) ,qty_ord number (5) , qty_deld
number (5) );

The ord_ty contains a record for each order - itemcode, the quantity ordered and the
quantity delivered. To use this data type as the basis for a nested table a new abstract
data type has to be created and is done as shown below:
SQL> create type ord_nt as table of ord_ty;

The "as table of' clause tells Oracle that this type will be used as the basis of a nested
table. This type i.e., ord_nt can be used to create a table i.e., ordecmaster.
SQL> create table orderJlUister (orderno varchar2 (5), odate date,vencode varchar2 (5) ,dets
ord_nt) nested table dets store as ord_nt_tab;

When a table is created it includes a table data type and the name of the table that will
be used to store the nested table's data is specified. In the example that is given above
the nested table is stored in a table that is named ord_nt_tab. The data for the nested
table is not stored 'in-line' with the rest of the table's data. Instead it is stored apart
from the main table. Thus the dets column will be stored in one table and the data for
ordemo, odate and vencode is stored in a separate table. Oracle maintains pointers
between the tables.
Inserting Records into Nested Tables
SQL> insert into order_master values ('O100','18-jul-99','v001', ord_nt(
ord_ty('i100',10,5),ord_ty('i101',50,25), ord_ty('i102',5,5) ));

By Subhash Reddy Aedla Page 129 of 304


ORACLE

The command given above inserts values to the ordecmaster table. Dets column values
are stored in a separate nested table called ord_nCtab. These data stored in a nested
table ord_nCtab cannot be accessed directly using SQL command.
SQL> INSERT INTO TABLE(SELECT p.dets FROM order_master p WHERE p.orderno = 'O100')
VALUES ('i103',30,25);

The values for the dets collection column can be inserted using TABLE expression. Here
TABLE expression facilitates us to select dets column from the order_master table. Data
entered in the value clause is inserted into the nested table ord_nt_tab.
Querying Nested Tables
Nested tables support a greater variety of querying than varying arrays. The nature of
the table must be taken into consideration while querying. A nested table is a column
inside a table. To support queries of columns and rows of a nested table, Oracle
provides a new keyword i.e., Table. Assume that the nested table is a normal relational
table then, it could be queried using the normal select command as shown below:
SQL> select * from ord_nt_tab;

This would raise an error as shown below.


select * from ord_nt
ERROR at line 1:
ORA-04044: procedure, function, package, or type is not allowed here
A nested table is merely a data type and cannot be queried. A relational table is in
existence in the database and hence can be queried. A nested table does not exist until
it is used in a normal relational table and hence cannot be queried like a relational table.
In order to select columns from the nested table, the table has to be 'nested' first so
that it can be queried. This is the place where the Table expression is used.
To query, select the nested table column from the main table:
select t.dets from order_master t where t.orderno= 'O100'

Enclose the above query within the TABLE expression


table (select t.dets from order~ster t where t.orderno= 'O100')

Make use of the above query enclosed in TABLE function as if it were a table.
SQL> SELECT * FROM TABLE(SELECT t.dets FROM order_master t WHERE t.orderno.= 'O100’

Updating nested table values

By Subhash Reddy Aedla Page 130 of 304


ORACLE

Updates can be performed in the same manner as inserts. An example makes updates
clearer.
SQL> UPDATE TABLE(SELECT e.dets from order_master e WHERE e.orderno.'O100') p SET
VALUE(p) .ord_ty ('i103',50,45) WHERE p.1temcode . 'i103',

Deleting nested table values


Deletion of the records in the nested table is similar to updation. TABLE expression can
be used to perform the deletion of records.
SQL> DELETE FROM TABLE(SELECT e.dets FROM order_master e WHERE e.orderno . 'O100') p
WHERE p.1temcode = ‘i103' ;

Class Room Examples:


Example: 1
Abstract Types
--Creating a Abstract Type.
create or replace type address_ty as object
( hno varchar2(5),
area varchar2(10),
city varchar2(10),
pin number(5)
);
/
--Structure of the above Type
SQL> desc address_ty
Name Null? Type
----------------------------- -----------------
HNO VARCHAR2(5)
AREA VARCHAR2(10)
CITY VARCHAR2(10)
PIN NUMBER(5)
/
--Using the above Type as ur datatype in a table

By Subhash Reddy Aedla Page 131 of 304


ORACLE

create table student


( stno number(4),
name varchar2(10),
address address_ty,
course varchar2(10),
dos date
)
/
insert into student values (7000,'Anoop',
address_ty('1-1-1','Vidyanagar','Hyderabad',500013),
'Oracle',sysdate)
/
insert into student values (7001,'Bhuvana',
address_ty('2-2-2','Moulali','Hyderabad',500035),
'Oracle','15-Apr-2004')
/
insert into student values (7002,'Chandana',
address_ty('3-4-5','GandhiNagar','Secunderabad',500039),
'SqlServer','11-Apr-2004')
/
select * from student
/
select s.address.area from student s
/
select name,s.address.hno,s.address.area,s.address.city,course from student s
/
select name,s.address.area,s.address.city,course from student s
/

By Subhash Reddy Aedla Page 132 of 304


ORACLE

select name,s.address.area,dos from student s


/
update student s set s.address.area='Nallakunta' where name like 'Anoop'
/
--Structure of the Student Table.
SQL> desc student
Name Type
---------------------- ---------------
STNO NUMBER(4)
NAME VARCHAR2(10)
ADDRESS ADDRESS_TY
COURSE VARCHAR2(10)
DOS DATE
/
select s.stno,s.name,s.address.hno,s.address.area,s.address.city,s.address.pin,s.course,
s.dos from student s
/
delete from student s where s.address.area='Begumpet'
/
drop type address_ty
/

Varrays
Example:1
create type one_yr as varray(6) of number(3)
/
create type two_yr as varray(6) of number(3)
/

By Subhash Reddy Aedla Page 133 of 304


ORACLE

create type three_yr as varray(6) of number(3)


/
create table Results(stno number(4), name varchar2(20),
year1 one_yr, year2 two_yr,year3 three_yr)
/
insert into results values('7000','Anoop',
one_yr(70,56,82,54,92),
two_yr(89,78,67,65,76),
three_yr(82,78,67,74,71))
/
select column_name,data_type from user_tab_columns where table_name like
'RESULTS'
/
Example: 2
Creating VARRAY
Create Type TOOL_VA as VARRAY(5) of VarChar(25);

Creating a Table with VARRAY Column


Create Table Borrower( Name Varchar(25) Primary Key, Tools Tools_Va);

Inserting Records Into VARRAY


Insert into Borrower Values( ‘Raj’, Tools_VA(‘Keyboard’,’Mouse’));

Selecting Data from VARRAY


Select B.Name, N.*From Borrower B, TABLE(B.Tools) N;

We can use TABLE() to retrieve VARRAY values.

Selecting VARRAY values in PL/SQL Block


Declare

By Subhash Reddy Aedla Page 134 of 304


ORACLE

cursor borrower_cur is Select * from borrower;


Begin
for b_rec in borrower_cur loop
dbms_output.put_line(‘Name’ || b_rec.name)
for I in 1..b_rec.Tools.Count loop
dbms_output.put_line(b_rec.Tools(I));
end loop;
End loop;
End;
/

Nested Tables
Example: 1
create type ord_ty as object ( itemcode varchar2(5),
qty_ord number(5), qty_deld number(5) )
/
create type ord_nt as table of ord_ty;
/
create table order_master ( orderno varchar2(5),
odate date, vcode varchar2(5), details ord_nt )
nested table details store as ord_nt_tab
/
insert into order_master values ('o100','18-jun-99','v001',
ord_nt(ord_ty('i100',10,5),
ord_ty('i101',50,25),
ord_ty('i102',5,5)
) )
/
insert into order_master values ('o101','28-jul-99','v002',

By Subhash Reddy Aedla Page 135 of 304


ORACLE

ord_nt(ord_ty('i100',20,15),
ord_ty('i101',20,5),
ord_ty('i102',15,15)
) )
/
insert into order_master values ('o102','13-aug-99','v003',
ord_nt(ord_ty('i100',10,5),
ord_ty('i101',25,15),
ord_ty('i102',35,25)
) )
/
select * from order_master
/
update table ( select e.details from order_master e where e.orderno='o100' ) p
set value(p)=ord_ty('i103',50,45) where p.itemcode='i101'
/
update table
(select e.details from order_master e where e.orderno='o100') p
set value(p) = ord_ty('i100',20,15) where p.itemcode = 'i100'
/
select o.itemcode from the (select details from order_master where orderno='o100') o
/
select o.itemcode,o.qty_ord,o.qty_deld from the
( select details from order_master where orderno='o101') o
/
Example: 2
Creating Nested Table Type
Create Type ANIMAL_NT as TABLE of Animal_Ty;

By Subhash Reddy Aedla Page 136 of 304


ORACLE

Creating a Table with Nested Table Column


Create Table Breeder( BreederName Varchar(25), Animals Animal_Nt) nested table
Animals store as ANIMALS_NT_TAB;

*Here Aniamls_Nt_Tab is called as a out-of-line table.

Inserting Records into a Table having a Nested Table Column


Insert into Breeder Values(‘JANE’, Animals_Nt(Animal_Ty(‘DOG’,’BUTCH’,’31-MAR-
01’),Animal_Ty(‘DOG’,’ROVER’,’05-MAR-01’)));

Querying Nested Tables


Select BreederName, N.Name, N.BirthDate From Breeder, TABLE(Breeder.Animals) N
Where N.Name=‘BUTCH’;

Inserting a Record in to a Nested Table


Insert into TABLE(Select Animals from Breeder where BreederName = ‘JANE’)
Values (Animal_Ty(‘DOG’,’MARCUS’,’01-AUG-02’));

Updating a Record in a Nested Table


Update TABLE(Select Animals from Breeder where BreederName = ‘JANE’) N
Set N.BirthDate = ’01-Sep-01’ Where N.Name = ‘MARCUS’;

Select BreederName, N.Name, N.BirthDate From Breeder, Table(Breeder.Animals) N;

Deleting a Record from a Nested Table


DELETE FROM TABLE(SELECT ANIMALS FROM BREEDER WHERE BREEDERNAME='JANE') N
WHERE N.NAME='ROVER‘;

By Subhash Reddy Aedla Page 137 of 304


ORACLE

LOBs
A LOB is a Large Object. LOBs are use to store large, unstructured data, such as video,
audio, photo images etc. With a LOB you can store up to 4 Gigabytes of data. They are
similar to a LONG or LONG RAW but differ from them in quite a few ways.
Why use LOBs and not LONG or LONG RAW: -
LOBs offer more features to the developer than a LONG or LONG RAW. The main
differences between the data types also indicate why you would use a LOB instead of a
LONG or LONG RAW. These differences include the following: -
 You can have more than one LOB column in a table, whereas you are restricted to
just one LONG or LONG RAW column per table.
 When you insert into a LOB, the actual value of the LOB is stored in a separate
segment (except for in-line LOBs) and only the LOB locator is stored in the row, thus
making it more efficient from a storage as well as query perspective. With LONG or
LONG RAW, the entire data is stored in-line with the rest of the table row.
 LOBs allow a random access to its data, whereas with a LONG you have to go in for a
sequential read of the data from beginning to end.
 The maximum length of a LOB is 4 Gig as compared to a 2 Gig limit on LONG
 Querying a LOB column returns the LOB locator and not the entire value of the LOB.
On the other hand, querying LONG returns the entire value contained within the
LONG column.
LOB types:
You can have two categories of LOBs based on their location with respect to the
database. The categories include internal LOBs and external LOBs. As the names
suggest, internal LOBs are stored within the database, as table columns. External LOBs
are stored outside the database as operating system files. Only a reference to the
actual OS file is stored in the database. An internal LOB can also be persistent or
temporary depending on the life of the internal LOB.
An internal LOB can be one of three different data types as follows: -
 CLOB – A Character LOB. Used to store character data.
 BLOB – A Binary LOB. Used to store binary, raw data
 NCLOB – A LOB that stores character data that corresponds to the national character
set defined for the database.

By Subhash Reddy Aedla Page 138 of 304


ORACLE

The only external LOB data type in Oracle 8i is called a BFILE.


 BFILE - Short for Binary File. These hold references to large binary data stored as
physical files in the OS outside the database.
LOB Locator:
Associated with each LOB is a locator. A locator is a pointer to the actual location of the
LOB value. The locator associated with internal LOBs is called a LOB locator, while the
locator associated with external LOBs is called a BFILE locator. When you store data in a
LOB column, you also store a LOB locator with it. This LOB locator is what is returned to
you when you query the LOB column, the actual value can then be got using this locator.
A LOB can be initialised to either a NULL value or made empty. The basic difference has
to do with the locator. If you set a LOB to NULL, the LOB has no locator or value stored
in the column. The value stored will be NULL. An empty LOB on the other hand has a
locator as well as data of length 0 stored in the column.
Before you actually start writing data to a LOB column using the various programming
interfaces provided by Oracle, you need to make it non-null by populating it with a
locator. To do this, use the built-in functions EMPTY_BLOB () for BLOBs, EMPTY_CLOB ()
for CLOBs and NCLOBs. For BFILEs, use the BFILENAME () method to initialise a BFILE
column to point to an OS file. Remember when you query a LOB column, only the
locator is returned to you.
Difference between Internal LOBs and External LOBs:
The major difference between the internal LOBs and external LOBs are as follows: -
1. Internal LOBs are stored in the database. External LOBs are stored outside the
database in operating system files.
2. Internal LOBs can take part in transactions. In the event of a failure, internal LOBs
can be recovered and changes made to them can be committed or rolled back.
External LOBs do not participate in transactions. The BFILE type allows only read
access to the operating system files. Changes to the external LOBs must be done out
with the database through the underlying OS.
3. Types of internal LOBs include CLOB, NCLOB and BLOB. The only external LOB is a
BFILE.
4. Internal LOBs use copy semantics. That is when you insert/update a LOB with a LOB
from another row in the table, the LOB locator as well as the LOB value are copied to

By Subhash Reddy Aedla Page 139 of 304


ORACLE

the row. External LOBs on the other hand use reference semantics. That is only the
BFILE location is copied and not the actual operating system file.
5. Each internal LOB column has a distinct LOB locator for each row and a distinct copy
of the LOB value. Each BFILE column has its own BFILE locator for each row.
However you could have two rows in the table that contain BFILE locators pointing
to the same operating system file.
Data Definition Language (DDL) commands and LOBs:
This section tells you how to create a table with LOB columns and also how to alter or
modify details of a LOB column in a table.
Creating a Table having LOB columns: -
You can create tables that have one or more LOB columns of the same or different type.
When you create a LOB column you also have the option of specifying if you want the
data within the LOB to be stored in-line or out-of-line. This is done using the ENABLE |
DISABLE STORAGE IN ROW clause. If you enable storage in the row, Oracle stores the
LOB value within the row, provided the length of the row (and the locator) is less than
4K. If it changes to more than 4K, then the LOB value will be moved out of the row into
the LOB segment. Only the locator is stored within the row.
It is important to note that when you create LOB column(s), you are actually creating
separate LOB segments. These LOB segments can be in the same tablespace as your
table. However you also have the option of specifying a different tablespace for the LOB
segment.
In addition, for each LOB column you create, Oracle implicitly creates a LOB index. This
index is maintained by Oracle and you cannot alter or drop it.
The name of the LOB segment defaults to SYS_LOBxxxx, where xxxx is a hexadecimal
number. The name of the LOB index defaults to SYS_ILxxxx where xxxx is a hexadecimal
number. The hexadecimal numbers for both the LOB segment and the LOB index are
the same.
When creating a LOB column you have the option of specifying the name of the LOB
segment as well as the LOB index. In addition you also can specify which tablespace
they go into, the storage details etc.
To create tables with LOB columns, you specify one of the LOB types as the data type of
the column. So, for example, the following statement
CREATE TABLE lobtable
(employee_id NUMBER,
resume CLOB,

By Subhash Reddy Aedla Page 140 of 304


ORACLE

comments CLOB);
would create a table lobtable having 3 columns, two of which are LOB columns. For
each of these LOB columns, you would have implicitly created a LOB segment and a LOB
index. To view information about the LOB columns you’ve created, check out the
XXX_LOBS (where XXX could be ALL, DBA or USER) dictionary views. For our lobtable,
we find the following information: -
SQL> SELECT table_name “Table”, column_name “Column”, segment_name “Segment”,
2 index_name “Index”
3 FROM user_lobs;
Table Column Segment Index
---------------- ------------------ ----------------------------------------- ------------------------------------
LOBTABLE COMMENTS SYS_LOB0000016119C00002$$ SYS_IL0000016119C00002$$
LOBTABLE RESUME SYS_LOB0000016119C00003$$ SYS_IL0000016119C00003$$
SQL>SELECT segment_name, segment_type, tablespace_name
2 FROM user_segments
3 WHERE segment_name like 'SYS_LOB%';
SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME
---------------------------------------- ------------------------ ------------------------------
SYS_LOB0000016119C00002$$ LOBSEGMENT USERS
SYS_LOB0000016119C00003$$ LOBSEGMENT USERS
SQL> SELECT segment_name, segment_type, tablespace_name
2 FROM user_segments
3 WHERE segment_name like 'SYS_IL%';
SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME
---------------------------------------- ------------------------- -----------------------------
SYS_IL0000016119C00002$$ LOBINDEX USERS
SYS_IL0000016119C00003$$ LOBINDEX USERS
When creating tables with LOB columns, you can specify the name of the LOB segment,
the LOB index, storage characteristics and LOB specific details. This is done using the
LOB clause of the CREATE TABLE statement. Although you can specify details for the
LOB index, this clause is deprecated as of Oracle 8i. You can still use it however without
an error, but it is a good idea to leave it out and let Oracle manage the index details. The
general syntax for this is as follows: -
CREATE TABLE <tabname>
(col_list)
[Physical attributes]

By Subhash Reddy Aedla Page 141 of 304


ORACLE

[Storage details]
*LOB (<lobcol1> *, <lobcol2>…+) STORE AS *<lob_segment_name>+
([TABLESPACE <name>]
[{ENABLE | DISABLE} STORAGE IN ROW]
[CHUNK <chunk_size>]
[PCTVERSION <version_number>]
[{CACHE | NO CACHE [{LOGGING | NO LOGGING}]
| CACHE READS [{LOGGING | NOLOGGING}]}]
[<storage_clause_for_LOB_segment>]
[INDEX [<lob_ind_name>] [physical attributes] [<storage_for_LOB_index>]]
)
]
*LOB (<lobcol1> *, <lobcol2>….+)…+
The LOB clause can be specified for a single LOB or for some/all LOBs in your table. If
you specify more than one LOB column in a single LOB clause, you cannot name the LOB
segments. You can use the LOB clause with several LOB columns for example if you
wanted to specify the same storage or other attributes for all of them.
Using the LOB clause above, we could re-create our lobtable table as follows, specifying
the tablespace and other details for one or more LOB columns.

Example 1: - Specifying names for the LOB segment as well as the LOB index for each of
the LOB columns
SQL> CREATE TABLE lobtable (employee_id NUMBER,
resume CLOB, comments CLOB)
LOB (comments) STORE AS comments_seg
(TABLESPACE lobtbs
CHUNK 4096 CACHE
STORAGE (MINEXTENTS 2)
INDEX comments_ind (TABLESPACE indxtbs
STORAGE (MAXEXTENTS UNLIMITED)
)
)
LOB (resume) STORE AS resume_seg
(TABLESPACE lobtbs
ENABLE STORAGE IN ROW
INDEX resume_ind (TABLESPACE indxtbs)
);

By Subhash Reddy Aedla Page 142 of 304


ORACLE

SQL> SELECT table_name "TABLE", column_name "COLUMN", segment_name


"SEGMENT",
2 index_name "INDEX"
3 FROM user_lobs;
TABLE COLUMN SEGMENT INDEX
------------------ -------------------- ------------------------- -------------------------
LOBTABLE COMMENTS COMMENTS_SEG COMMENTS_IND
LOBTABLE RESUME RESUME_SEG RESUME_IND
Example 2: - Specifying common values for all columns together.
SQL> CREATE TABLE lobtable
(employee_id NUMBER,
resume CLOB,
comments CLOB)
LOB (resume, comments) STORE AS
(CHUNK 4096 TABLESPACE lobtbs
ENABLE STORAGE IN ROW
CACHE
)
)
In the above case, remember you haven’t given a name to either the LOB segment or
the LOB index and they will both default to their default names (SYS_LOBXXX and
SYS_ILXXX).
Note: - For details on what the various options within the LOB clause mean, look up the
Oracle SQL Reference Manual.
Altering LOB columns in a table: -
Once you create a LOB column in a table, you can modify some parts of its definition.
However you cannot change the chunk size value. Neither can you change the settings
for ENABLE | DISABLE STORAGE IN ROW, except when moving the table using the MOVE
clause. You can change the PCTVERSION, CACHE and LOGGING options as well as the
storage details. To change the tablespace information, you can use the MOVE clause of
the ALTER TABLE statement.
The syntax for the ALTER TABLE statement is as follows. Please note that this is specific
to changes to a LOB column only, and does not include other options.
Syntax: -

By Subhash Reddy Aedla Page 143 of 304


ORACLE

ALTER TABLE <tname>


{ADD (<lobcol> <LOBTYPE> <lob_clause_same_as_for_CREATE>) |
MODIFY LOB (<lobcol>) ([<storage_clause>]
[PCTVERSION <version_number>]
[{CACHE | NOCACHE [{LOGGING | NOLOGGING}] |
CACHE READS [{LOGGING | NOLOGGING}]
}]
)|
MOVE [ONLINE] [<physical_attributes>][TABLESPACE <tname>]
[{LOGGING | NOLOGGING}] [<lob_clause_same_as_for_CREATE>]

Example 1: - Altering a table to add a new LOB column


SQL> ALTER TABLE lobtable
ADD (photo BLOB)
LOB (photo) STORE AS photo_seg
(TABLESPACE lobtbs CHUNK 4096 PCTVERSION 5
ENABLE STORAGE IN ROW);
Example 2: - Modifying an existing LOB column in a table
SQL> ALTER TABLE lobtable
MODIFY LOB (photo) (STORAGE (maxextents unlimited) cache);
Manipulating LOBs:
Initialising LOBs to NULL or empty: -
You can initialise an internal LOB to either a NULL or to be empty. An external LOB
column can be initialised to either NULL or to a filename.
You use either the EMPTY_BLOB () or the EMPTY_CLOB () methods to initialise an
internal LOB to be empty (see how to insert into LOBs below). These functions can be
used even with the DEFAULT clause of the CREATE/ALTER TABLE statements.

Example 1: - Creating a table with default values for the LOB column in it.
SQL> CREATE TABLE lobtable
(employee_id NUMBER,
photo BLOB DEFAULT EMPTY_BLOB(),
resume CLOB DEFAULT EMPTY_CLOB(),
comments CLOB DEFAULT EMPTY_CLOB());

By Subhash Reddy Aedla Page 144 of 304


ORACLE

Example 2: - Altering the default values for LOB columns in a table.


SQL> ALTER TABLE lobtable
MODIFY (photo DEFAULT empty_blob (),
resume DEFAULT empty_clob());
Remember, you cannot call any of the functions in the Oracle programming interfaces
(such as the PL/SQL package DBMS_LOB and OCI calls) on a LOB that is NULL, because
they work on LOB locators. You need to either initialise it to a value or set it to be
empty.
DML operations on internal and external LOBs: -
You can use the SQL DML commands including INSERT, UPDATE and DELETE with LOB
columns.
As mentioned, if you are using programming interfaces to work with LOBs, you need to
have a locator assigned to the LOB column. You can do this using the INSERT statement,
which can be used to assign a value, set the column to empty or even set the value to
NULL.
To insert NULL values into LOB columns in a row, do the following
SQL> INSERT INTO lobtable VALUES (1, null, null, null);
To insert either a value or make the LOB empty, do the following
SQL> INSERT INTO lobtable (employee_id, photo, resume, comments)
VALUES (1, empty_blob (), empty_clob (), ‘This is a test’);
When working within PL/SQL, you would normally want to first set the LOB values to
empty and then read back the details and make your changes using the lob locator.
These values can then be written back into the database. One way of doing this is to
first perform an INSERT as above, then SELECT the populated lob locator into a local
variable, make your changes using the lob locator and then write the information back.
An easier way to accomplish this would be to use the RETURNING clause of the INSERT
statement to return the new locator into a variable directly.
An example follows: -
DECLARE
L_comments CLOB;
L_photo BLOB;
L_resume CLOB;
BEGIN
INSERT INTO lobtable
VALUES (1, empty_blob (), empty_clob (), empty_clob ())

By Subhash Reddy Aedla Page 145 of 304


ORACLE

RETURNING photo, comments, resume INTO


L_photo, l_comments, l_resume;
/* You can then use DBMS_LOB package or whatever to make required
changes using the local variables that point to the locators */
COMMIT;
END;
To assign a BFILE column, you will have to use the BFILENAME () function. This function
takes two arguments, one the logical directory (which has to be mapped to a physical
directory on the OS) and the filename. Before you use the BFILENAME routine, you will
have to create a DIRECTORY object.
An example follows: -
SQL> CREATE DIRECTORY lobdir AS ‘C:\mydir\lobs\’;
SQL> CREATE TABLE externalTable
(photo BFILE);
SQL> INSERT INTO externalTable
VALUES (BFILENAME (‘lobdir’,’test.bmp’));
The same concepts you followed for INSERT can also be applied to UPDATE. So you
could update a LOB to be empty, null or set it to a value. You can also assign a row value
from a SELECT query.
Some examples: -
SQL> UPDATE lobtable
SET comments = empty_clob();
SQL> UPDATE lobtable
SET photo = null;
SQL> UPDATE lobtable
SET comments = (SELECT mycomments FROM myCommentsTable);
SQL> UPDATE externalTable
SET photo = BFILENAME (‘lobdir’,’another.bmp’);
Deleting rows from a table containing LOB columns is no different from deleting any
other table. Since you are working on the row as a whole, not an individual column. So
you could do the following: -

By Subhash Reddy Aedla Page 146 of 304


ORACLE

SQL> DELETE lobtable;


SQL> DELETE lobtable WHERE employee_id = 1;
Remember though, that with BFILEs you are actually only storing references to external
files. So when you delete a row containing a BFILE, all you are doing is deleting the
BFILE locator. The actual file will still exist on the operating system, till you delete it
manually using OS utilities.
Using the provided DBMS_LOB package:
Oracle provides the DBMS_LOB package for working with LOBs in general. This package
contains a whole load of procedures and functions that let you perform quite complex
operations using LOBs, including finding a pattern within a LOB, getting a sub-string,
opening and closing LOBs in different modes, add/replace content in a LOB etc.
We look at only some of the procedures and functions here. To get a complete listing,
either look up the ‘Oracle Supplied PL/SQL Packages’ manual or do a ‘desc dbms_lob’ at
the SQL prompt.
Persistent LOBs:
All DBMS_LOB packages work off a LOB locator. So you must provide a locator that
represents a LOB that is either in your database table or on your operating system. For
both internal and external LOBs, you must therefore already have initialised your LOB
(using either the empty_blob, empty_clob or bfilename functions). You can then use
the SELECT statement to fetch the LOB locator into a local variable and work off the
locator variable.
One thing to remember when working with the DBMS_LOB package, especially with
reference to procedures/functions that modify an internal LOB, is that you have to
explicitly lock rows before you perform a modification. The packaged
procedures/functions do not lock the row containing the LOB you are trying to modify.
A list of some of the packaged procedures and functions are given below.
Methods for manipulating content of the LOB: -
DBMS_LOB.INSTR (
lob_loc IN {BLOB | BFILE | CLOB CHARACTER SET ANY_CS},
pattern IN {RAW | VARCHAR2 CHARACTER SET lob_loc%CHARSET},
offset IN INTEGER: = 1,

By Subhash Reddy Aedla Page 147 of 304


ORACLE

nth IN INTEGER: = 1) RETURN INTEGER;


This method returns the position of the nth occurrence of the patter starting from the
specified offset. The pattern cannot include wild-card characters such as those used for
the LIKE operator (% or _). If the pattern is not found, a value 0 is returned.
DBMS_LOB.COMPARE (
lob_loc1 IN {BLOB | BFILE | CLOB CHARACTER SET ANY_CS},
lob_loc2 IN {BLOB | BFILE | CLOB CHARACTER SET ANY_CS},
amount IN INTEGER := 4294967295,
offset IN INTEGER := 1,
offset 2 IN INTEGER := 1) RETURN INTEGER;
This function compares two lobs, either part of the lobs or whole lobs. You can only
compare LOBs of the same type. It returns 0 if the data matches exactly over the range
specified by the offset and amount values. Else a non-zero integer is returned.
DBMS_LOB.SUBSTR (
lob_loc IN {BLOB | BFILE | CLOB CHARACTER SET ANY_CS},
amount IN INTEGER: = 32767,
offset IN INTEGER: = 1)
RETURN {RAW | VARCHAR2 CHARACTER SET lob_lob%CHARSET}
This function returns the sub-string of a LOB data value. The type of the returned
VARCHAR2 buffer must match the form of the CLOB parameter.
DBMS_LOB.TRIM (
lob_loc IN OUT NOCOPY {BLOB | CLOB CHARACTER SET ANY_CS},
new_length IN INTEGER);
This procedure trims the value of the LOB value to the length you specify. Trying to trim
an empty LOB does not do anything. If the new length you specify is greater than the
length of the LOB value, an exception is raised.
DBMS_LOB.GETLENGTH (
Lob_loc IN {BLOB | BFILE | CLOB CHARACTER SET ANY_CS})
RETURN INTEGER;

By Subhash Reddy Aedla Page 148 of 304


ORACLE

This function returns the length of the specified LOB. Remember an empty LOB has a
length 0.
DBMS_LOB.COPY (
dest_lob IN OUT NOCOPY {BLOB | CLOB CHARACTER SET ANY_CS},
src_lob IN {BLOB | CLOB CHARACTER SET dest_lob%CHARSET},
amount IN INTEGER,
dest_offset IN INTEGER: = 1,
src_offset IN INTEGER:= 1);
This procedure is used to copy all or part of the source internal LOB into the destination
internal LOB. If the offset specified for the destination LOB is beyond the end of data
currently in the LOB, zero-byte fillers or spaces are inserted into the BLOB or CLOB
respectively. If the offset specified is less than current length of the destination LOB,
then data in the destination LOB will be overwritten by the new data.
Methods to work on a BFILE: -
The following are methods that are used with external LOBs or BFILE. Not all
functions/procedures have been included. Please check out the on-line documentation
for a complete listing.
DBMS_LOB.LOADFROMFILE (
Dest_lob IN OUT NOCOPY {BLOB | CLOB CHARACTER SET ANY_CS},
Src_lob IN BFILE,
Amount IN INTEGER,
Dest_offset IN INTEGER: = 1,
Src_offset IN INTEGER: = 1)
This procedure copies all or part of the source BFILE into the destination BFILE. This
procedure is quite similar to the way COPY works, except that it works with BFILEs
DBMS_LOB.OPEN (
lob_loc IN OUT NOCOPY {BLOB | BFILE | CLOB CHARACTER SET ANY_CS},
open_mode IN BINARY_INTEGER);
This procedure opens the given internal or external LOB in one of two modes, either
read-only or read-write. The value for the open_mode parameter could be either

By Subhash Reddy Aedla Page 149 of 304


ORACLE

lob_readonly or lob_readwrite. A BFILE can only be opened in the read-only mode, that
is the only valid value for open_mode when working with BFILE is lob_readonly.
DBMS_LOB.FILECLOSE (
file_loc IN OUT NOCOPY BFILE);
DBMS_LOB.FILECLOSEALL;
The above two procedures are used to close an opened BFILE. The first takes in a BFILE
locator and closes the BFILE referenced by it. The second function closes all open BFILEs
in the current session.
Reading and Writing into LOBs:
DBMS_LOB.READ (
lob_loc IN {BLOB | BFILE | CLOB CHARACTER SET ANY_CS},
amount IN OUT NOCOPY BINARY_INTEGER,
offset IN INTEGER,
buffer OUT {RAW | VARCHAR2 CHARACTER SET lob_lob%CHARSET};
This procedure reads the specified portion of the LOB and places it in the buffer
specified. The form of the VARCHAR2 buffer must match the form of the CLOB
parameter.
DBMS_LOB.APPEND (
Dest_lob IN OUT NOCOPY {BLOB | CLOB CHARACTER SET ANY_CS},
Src_lob IN {BLOB | CLOB CHARACTER SET dest_lob%CHARSET});
Use the append procedure to add contents of the source LOB into the destination LOB.
Obviously you can only append to/from LOBs of the same type, so CLOB to CLOB or
BLOB to BLOB.
DBMS_LOB.WRITE (
Lob_loc IN OUT NOCOPY {BLOB | CLOB CHARACTER SET ANY_CS},
Amount IN BINARY_INTEGER,
Offset IN INTEGER,
Buffer IN {RAW | VARCHAR2 CHARACTER SET ANY_CS});
The write procedure is used to write a specified amount of data from the buffer into an
internal LOB, starting at the offset position. Any data already in the LOB is overwritten.
The form of the VARCHAR2 buffer must match the form of the CLOB parameter.

By Subhash Reddy Aedla Page 150 of 304


ORACLE

There are many more procedures and functions that haven’t been included in this list.
Please check the documentation for a complete list.
Examples for working with persistent LOBs: -
Example 1: -
DECLARE
L_resume CLOB;
L_comments CLOB;
Comm_buf VARCHAR2 (30): = 'Joined company on the 10/10/01';
Resume_buf VARCHAR2 (30): = ‘Resume for Scott’;
BEGIN
/* Create a row in our lobtable, initialising the lob columns to empty and
returning the locator values into local variables */
INSERT INTO lobtable (employee_id, resume, comments)
VALUES (10, empty_clob (), empty_clob ())
RETURNING resume, comments INTO L_resume, L_comments;

-- Now explicitly open both LOB locators in read-write mode


dbms_lob.open(L_resume, dbms_lob.lob_readwrite);
dbms_lob.open(L_comments, dbms_lob.lob_readwrite);

--Write info from the buffers into the LOBs pointed to by the locators
dbms_lob.write(L_resume, length(Resume_buf), 1, Resume_buf);
dbms_lob.write(L_comments, length(Comm_buf), 1, Comm_buf);

--An example of how to use the instr function


IF (dbms_lob.instr (L_resume, 'Scott', 1,1) > 0) THEN
dbms_output.put_line('This is the resume for employee Scott ');

By Subhash Reddy Aedla Page 151 of 304


ORACLE

END IF;

--Now print out contents of the


dbms_output.put_line('Printing the contents of the two LOBs');
dbms_output.put_line('L_RESUME = ' || dbms_lob.substr(L_resume,
dbms_lob.getlength(L_resume),1));
dbms_output.put_line('L_COMMENTS = ' || dbms_lob.substr(L_comments,
dbms_lob.getlength(L_comments),1));

--Close opened LOBs before you commit work.


dbms_lob.close(L_resume);
dbms_lob.close(L_comments);
Commit;
END;

The output of this block is


SQL>/
This is the resume for employee Scott
Printing the contents of the two LOBs
L_RESUME = Resume for Scott
L_COMMENTS = Joined company on the 10/10/01

PL/SQL procedure successfully completed.


Example 2: -
DECLARE
l_bfile BFILE;
l_dir VARCHAR2(30);
l_file VARCHAR2(30);

By Subhash Reddy Aedla Page 152 of 304


ORACLE

BEGIN
SELECT myfile INTO l_bfile
FROM lobtest;
IF (dbms_lob.fileexists (l_bfile) = 1) THEN
IF (dbms_lob.fileisopen (l_bfile) = 1) THEN
dbms_output.put_line('File is open');
ELSE
dbms_lob.open(l_bfile, dbms_lob.lob_readonly);
END IF;
dbms_output.put_line('Length of file is ' || dbms_lob.getlength(l_bfile));
ELSE
dbms_lob.filegetname(l_bfile, l_dir, l_file);
dbms_output.put_line('File with name ' || l_file || ' does not exist in directory '||
l_dir);
END IF;
END;

The output of this PL/SQL code is as follows: -


SQL> /
Length of file is 23

PL/SQL procedure successfully completed.


Temporary LOBs:
Oracle provides you with the functionality of creating temporary LOBs. As the name
suggests, they are not permanent and hence not stored in database tables. They
normally exist for the duration of a user session. Though you can, at the time of
creation, specify that you want the temporary LOB to exist only for the duration of the
current program call. You normally use them like you would use local variables, you
need them to perform some operations on LOB data without having to store it in the
database.

By Subhash Reddy Aedla Page 153 of 304


ORACLE

You can create, access, update and then free your temporary LOBs. There is no logging
or redo information generated for temporary LOBs, thus giving you better performance.
Temporary LOBs are created in your temporary tablespace. You use
DBMS_LOB.CREATETEMPORARY() procedure to create a temporary LOB. When you
create a temporary LOB you are automatically setting it to empty. You cannot use the
EMPTY_BLOB or EMPTY_CLOB functions with temporary LOBs.
The following procedures and functions are provided to you as part of the DBMS_LOB
package to work with temporary LOBs.
Creating a temporary LOB:
DBMS_LOB.CREATETEMPORARY (
lob_loc IN OUT NOCOPY {BLOB | CLOB CHARACTER SET ANY_CS},
cache IN BOOLEAN
duration IN PLS_INTEGER := DBMS_LOB.SESSION)

This procedure creates a temporary LOB with the locator returned in lob_loc. In
addition, it also creates a temporary LOB index in the default temporary tablespace. The
duration parameter specifies the lifetime of the temporary LOB and defaults to the
session. If you want, you can also set it to the current program call using the integer
DBMS_LOB.CALL.
Freeing the temporary LOB:
DBMS_LOB.FREETEMPORARY (
lob_loc IN OUT NOCOPY {BLOB | CLOB CHARACTER SET ANY_CS})

This procedure frees the created temporary CLOB or BLOB in your temporary
tablespace. Once you call this procedure, the lob locator associated with the temporary
LOB is marked invalid. If you subsequently assign this lob locator to another lob locator,
the latter one is also freed and marked invalid.
Checking if a LOB is temporary:
DBMS_LOB.ISTEMPORARY (
Lob_loc IN {BLOB | CLOB CHARACTER SET ANY_CS})
RETURNS integer

By Subhash Reddy Aedla Page 154 of 304


ORACLE

Use this function to determine if a given lob locator points to a temporary or persistent
LOB. It returns an integer value: 1 for a temporary LOB and 0 for a persistent LOB.
An example:
DECLARE
tempLOB CLOB;
amt NUMBER := 14;
position NUMBER := 1;
buffer VARCHAR2(20) := 'this is a test';
BEGIN
/*Create and open a temporary lob for reading and writing */
DBMS_LOB.CREATETEMPORARY (tempLOB, true);
IF (DBMS_LOB.ISTEMPORARY (tempLOB) = 1) THEN
dbms_output.put_line('A temporary LOB has been created');
ELSE
dbms_output.put_line('Not a temporary LOB');
END IF;
DBMS_LOB.OPEN (tempLOB, DBMS_LOB.LOB_READWRITE);

/* write the buffer data into the temporary LOB*/


DBMS_LOB.WRITE (tempLOB, amt, position, buffer);

/* Now you can manipulate the temporary LOB*/


dbms_output.put_line('No of chars in the temporary LOB= ' ||
DBMS_LOB.GETLENGTH (tempLOB));
dbms_output.put_line('Content = ' || DBMS_LOB.SUBSTR(tempLOB,
DBMS_LOB.GETLENGTH (tempLOB), 1)
/*close and free up the temporary LOB

By Subhash Reddy Aedla Page 155 of 304


ORACLE

DBMS_LOB.CLOSE (tempLOB);
DBMS_LOB.FREETEMPORARY (tempLOB);
END;

The output of the above code is as follows: -


SQL> /
A temporary LOB has been created
No of chars in the temporary LOB= 14
Content = this is a test

PL/SQL procedure successfully completed.


Restrictions on LOBS:
There are a few restrictions on how you can use LOBs. In particular,
 LOBs cannot be used in the GROUP BY, ORDER BY, SELECT DISTINCT, joins and
aggregate function.
 They cannot be part of clustered tables.
 They are not analysed with the ANALYZE command.
 You cannot include them in partitioned index-organised tables.
 They are not allowed in VARRAYs.
 NCLOBs are not allowed as object attributes.

By Subhash Reddy Aedla Page 156 of 304


ORACLE

Oracle Flashback Query


Sometimes it is a rouge query, sometimes a simple data cleanup effort by the users,
whatever may the cause be, inadvertent data-loss is a very common phenomenon.
Backup and recovery capabilities are provided by the database management systems
which ensure the safety and protection of valuable enterprise data in case of data loss
however, not all data-loss situations call for a complete and tedious recovery exercise
from the backup. Oracle introduced flashback features in Oracle 9i and 10g to address
simple data recovery needs. Flashback query allows a user to view the data quickly and
easily the way it was at a particular time in the past, even when it is modified and
committed, be it a single row or the whole table.
Creating the test tables:
For the examples we are going to use the following two tables:
SQL> desc employee;
Name Type
------ ------------
EMP_ID NUMBER
NAME VARCHAR2 (30)
AGE NUMBER
We will also create a temporary table - employee_TEMP - with exactly the same
definition as the Employee table. This temporary table will be used as a container to
store the recovered data. Even though we can recover the data to the original table, we
prefer to use a separate table, which makes it easier to compare the recovered data to
the data currently in the actual table.
For all our tests we will:
1. Have some records entered into the employee table.
2. Display the records using a simple select.
3. Delete or update some or all of the records from the employee table and commit
the transaction.
4. Display the employee table data again to ensure that records are, in fact
removed or altered.
5. Try to recover the lost data into the employee_temp table.
Now that that the system is configured, privileges are granted and test tables are
created, we can test the flashback query feature.

By Subhash Reddy Aedla Page 157 of 304


ORACLE

There are two approaches to using the flashback queries. One is a time based approach
and the other uses the SYSTEM CHANGE NUMBER - SCN - to identify the point we want
to go back to. Each of these approaches employs the AS OF clause as well as an Oracle
supplied package DBMS_FLASHBACK. Both are discussed here.
Using the Flashback Query with AS OF clause:
Suppose we want to recover data we have accidentally deleted for some of the
employees from the EMPLOYEE table and have committed the transaction. The
following query shows how we will use the AS OF clause for recovering data to a certain
point in time, at which we know our data existed.
SQL> INSERT INTO EMPLOYEE_TEMP
(SELECT * FROM EMPLOYEE AS OF TIMESTAMP ('13-SEP-04 8:50:58','DD-MON-YY
HH24: MI: SS'
Now if we ran a SELECT statement on EMPLOYEE_TEMP table, we will see all the lost
data in this temporary table, which we can add to the actual employees table.
Using a point in time is way of going back, another way of telling the system how far to
go back is the use of SCN - System Change Number. The procedure is the same as
earlier, trying to recover lost data using the DBMS_FLASHBACK utility. Only this time
instead of using the time we are using the system change number - SCN to enter the
flashback mode. This SCN number can be obtained before the transaction is initiated by
using the GET_SYSTEM_CHANGE_NUMBER function of the DBMS_FLASHBACK utility as
follows.
SQL> select DBMS_FLASHBACK. GET_SYSTEM_CHANGE_NUMBER from dual;
You do not have to be in the flashback mode to run this statement. As you might have
already guessed, the AS OF clause is used with SCN number as shown below.
SQL> INSERT INTO EMPLOYEE_TEMP
(SELECT * FROM EMPLOYEE AS OF SCN 10280403339);
We have recovered the data again but this time using the SCN number.
Using the DBMS_FLASHBACK package:
Prior to Oracle 9i release 2, the only way to use the flashback query feature was through
the use of the utility package DBMS_FLASHBACK. In order to use this method, the user
had to specify the intention to enter the flashback mode by supplying the time to which
the user wished to go back to. This was done by using the ENABLE_AT_TIME function of

By Subhash Reddy Aedla Page 158 of 304


ORACLE

the DBMS_FLASHBACK package to enter the flashback mode, followed by a DISABLE


function to resume normal operation.
DECLARE
CURSOR emp_cur IS
SELECT * FROM EMPLOYEE;
v_rec emp_cur%rowtype;
BEGIN
DBMS_FLASHBACK.ENABLE_AT_TIME ('13-SEP-04 08:10:58');
open emp_cur;
DBMS_FLASHBACK.DISABLE;
LOOP
fetch emp_cur into v_rec;
EXIT WHEN emp_cur%NOTFOUND;
INSERT INTO EMPLOYEE_TEMP VALUES
(v_rec.emp_id,
v_rec.name,
v_rec.age );
END LOOP;
close emp_cur;
COMMIT;
END;
Using the DBMS_FLASHBACK package with time
Again using the similar procedure as before, we will recover data into out
EMPLOYEE_TEMP table using the SCN number instead of time as shown in the Figure 2,
by replacing line 6 with this line below and we are able to recover again.
DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER (10280403339);
Notice that we have entered into the flashback query mode in figure 2 line 6, DML
statements INSERT, UPDATE, or DELETE are not allowed until we exit flashback query
mode by issuing DBMS_FLASHBACK.DISABLE. Because of this limitation the cursor for
loop cannot be used in using the DBMS_FLASHBACK if we are using any of the above
DML statements inside the loop. Code with cursor for loops will run fine but will not go
back to the point in time we wanted to go and instead will fetch the data that is
currently in the table to be recovered rendering the whole exercise useless. An
addendum to the previous point is that FLASHBACK mode can be entered only at the
beginning of a transaction. If a DML statement has been issued, it must be committed
before we can enter the flashback mode.

By Subhash Reddy Aedla Page 159 of 304


ORACLE

It is worth mentioning that even when we use time instead of SCN number Oracle still
maps that time to an SCN number stored in the SMON_SCN_TIME every 5 minutes by
Oracle background process SMON.
Oracle 10G enhancements to Flashback:
Oracle 10G has enhanced the flashback feature further and has turned it into a much
more powerful feature by introducing numerous additions. Some of the more common
ones are discussed here.
 Flashback Table
 Flashback Drop
 Flashback Database
 Flashback Versions Query
 Flashback Transaction Query

The first three of these features are discussed here.


Flashback Table
Just like the flashback query helps retrieve rows of a table, FLASHBACK TABLE helps
restore the state of a table to a certain point in time even if a table structure changed
has occurred since then. The following simple command will take us to the table state at
the specified timestamp.
SQL> FLASHBACK TABLE Employee TO
TIMESTAMP ('13-SEP-04 8:50:58','DD-MON-YY HH24: MI: SS');
Not only does this command restore the tables but also the associated objects like
indexes, constraints etc.
Flashback Drop
So far we have recovered the lost data to a particular point-in-time back into a table
that exists in the database. Oracle 10g has provided another useful feature term as the
Flashback drop. For our example if a DROP TABLE has been issued for the table
EMPLOYEE we can still restore the whole table by issuing the following command.
SQL> FLASHBACK TABLE EMPLOYEE TO BEFORE DROP;
Bringing back dropped tables could not be any easier than this. RECYCLE BIN
It is worthwhile to take a little detour and familiarize ourselves with the feature in
Oracle 10g that enabls us to flashback. Oracle has introduced the RECYCLE BIN which is a
logical entity to hold all the deleted objects and works exaclty like the recylce bin
provided in Windows operating system for example. All the deleted objects are kept n

By Subhash Reddy Aedla Page 160 of 304


ORACLE

the recylce bin, these objects can be retrieved from the recycle bin or deleted
permanently by using the PURGE command. Either an indivisual object like a table or an
index can be deleted from the recycle bin:
SQL> PURGE TABLE Employee;
or the whole recylce bin can be 'emptied out' by using the PURGE command:
SQL> PURGE recyclebin;
If you take a look at the contents of the recycle bin using the following query,
SQL> select OBJECT_NAME, ORIGINAL_NAME, TYPE from user_recyclebin;
OBJECT_NAME ORIGINAL_NAME TYPE
---------------------------------------------------------------------------------------------------
BIN$G/gHMigrTRqHQukZSIpSLw==$0 EMPOLYEE TABLE
BIN$1UiHeUR7SymGHo20pTfGXA==$0 EMPLOYEE TABLE
BIN$6d6677f5T+K++npt+5p/jQ==$0 EMP_IDX1 INDEX
you will notice that the tables are not saved under their original names, instead they are
saved under their recycled names along with the column ORIGINAL_NAME that contans
the actual names of the objects. When the table is recoverd form the recycle bin, the
views and procedure using these tables that were rendered invalid at the time the table
was dropped remain invalid. The actual names of these objects indexes, views etc. have
to retrived from the recycle bin manually and applied to the table again. So for our
example the table rerieved from the recycle bin would have an index named
BIN$6d6677f5T+K++npt+5p/jQ==$0v instead of EMP_IDX1 and the actual name have to
be recoverd and applied from the recycle bin manually like this:
SQL> drop index BIN$6d6677f5T+K++npt+5p/jQ==$0;
SQL> create index EMP_IDX1 on EMPLOEE (EMPNO);
Flashback database
So far we have discussed the recovery of individual rows or individual objects. This
logically leads to the discussion of recovering the whole database to a point in time. Knit
tightly with the recovery manager - RMAN, the Flashback datbase feature provided in
Oracle 10g, provides yet another way of easy and efficient, point-in-time recovery in
case of data corruption or data loss. This is much faster than the traditional approach to
point-in-time recovery since no redo logs are required when using this approach. About
the Flashback database feature, Oracle documentation says the best: "Flashback
Database is like a 'rewind button' for your database."

By Subhash Reddy Aedla Page 161 of 304


ORACLE

As is generall y the case with most softwares, there is a speed/space trade-off here as
well. Flashback Database requires the creation and configurtion of an Oracle Flash
Recovery Area before this feature can be used.
Flash Recovery Area created by the DBA, is the allocation of space on the disk to hold all
the recovery related files in one, centralized place. Flash Recovery Area contains the
Flashback Logs, Redo Archive logs, backups files by RMAN and copies of control files.
The destination and the size of the recovery area are setup using the
db_recovery_file_dest and b_recovery_file_dest_size initializatin parameters. Now when
the setup is complete, let's see how the flashback database is used.
For this test suppose that a transaction ran that made significant changes ti the
database, yet this is not what the user intended. Going back and retrieving individual
objects and then recovernig and restoring the original data can be a very extensive, yet
timeconsuming and error-prone exercise. It is time to use the FLASHBACK DATABASE.
First the flashback is enabled to make Oracle database enter the flashback mode. The
database must be mounted Exclusive and not open. The database has to be in the
ARCHIVELOG MODE before we can use this feature. This is shown as below.
SQL> ALTER DATABASE ARCHIVELOG;
Now startup the database in EXCLUSIVE mode.
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT EXCLUSIVE
Now enter the flashback mode (the database should not be open at this time)
SQL> ALTER DATABASE FLASHBACK ON;
Issue the flashback command and take the database to the state it was in, one hour ago.
SQL> Flashback database to timestamp sysdate-(1/24);
After the system comes back with FLASHBACK COMPLETE, open the database.
SQL> ALTER DATABASE OPEN RESETLOGS;
Now if you select from any of the tables that were affected, you will see that the
affected tables are in the original state, i.e. an hour ago. And once again, we have the
option of using SCN instead of timestamp.
As is evident from this section, that while other flashback features are available to the
users of the database, the flashback database involves the DBA because of the system
level activities that have to be performed. Nevertheless, the whole exercise is much
simpler and easier than the traditional point-in-time recovery.

By Subhash Reddy Aedla Page 162 of 304


ORACLE

Flashback query is a powerful and useful feature introduced in Oracle 9i, and enhanced
greatly in Oracle 10g, that can help us recover data, lost or corrupted, due to human
error. One big advantages of using flashback over point-in-time recovery is that for the
latter not only transactions from the time of error to the current time would be lost but
also the system will be unavailable for the duration of the recovery. For flashback query,
on the other hand, there will be no down time needed and repair or recovery is less
labor and time intensive than what it used to be in earlier versions of Oracle. With the
new features like Recycle Bin, Flashback databases and Flashback Drop in Oracle 10g,
the flashback capability introduced in 9i has been improved tremendously now turning a
small feature into a powerful tool in the new Oracle releases.
Flashback is an insurance feature. Just like having car insurance does not mean that we
can be careless on the road, FLASHBACK too, should be considered another tool in the
belt, rather than a luxury that allows us to be careless about the data simply because we
have the ability to recover it easily.

By Subhash Reddy Aedla Page 163 of 304


ORACLE

Oracle Database 10g: The Database for the Grid


Grid computing is poised to drastically change the economics of computing. Grid
computing can dramatically lower the cost of computing, extend the availability of
computing resources, increase productivity, and improve quality.
The basic idea of grid computing is the notion of computing as a utility, analogous to the
electric power grid or the telephone network. As a client of the grid, you do not care
where your data is or where your computation is done. You want to have your
computation done and to have your information delivered to you when you want it.
From the server-side, the grid is about virtualization and provisioning. You pool all your
resources together and provision these resources dynamically based on the needs of
your business; thus achieving better resource utilization at the same time.
Today's mantra for computing is affordability. Enterprises are looking at ways to reduce
costs and increase efficiency of their processes and systems. Grid computing offers
exactly that. Grid computing increases the efficiency of enterprise resources by offering
a way to pool your hardware for processing and eliminate islands of underutilized
computers. You can create centralized pools of computing resources and dynamically
allocate these computing resources to the priorities of your organization.
At the highest level, the central idea of grid computing is computing as a utility. You
shouldn't care where your data resides, or which computer processes your request. You
should be able to request information or computation and have it delivered - as much as
you want, and whenever you want. This is analogous to how electric utilities work, in
that you don't know where the generator is, or how the electric grid is wired. You just
ask for electricity, and you get it. The goal is to make computing a utility-a commodity,
and ubiquitous. Hence it has the name, grid computing.
This view of utility computing is, of course, a client side view. From the server side, or
behind the scenes, grid computing is about resource allocation, information sharing, and
high availability. Resource allocation ensures that all those that need or request
resources are getting what they need. Resources are not standing idle while requests
are going unserviced. Information sharing makes sure that the information users and
applications need is available where and when it is needed. High availability ensures
that all the data and computation is always there-just as a utility company must always
provide electric power.
Grid computing transforms the way enterprises use resources. It virtualizes the use of
enterprise resources across servers in a data center, across data centers in an
enterprise, and across enterprises.

By Subhash Reddy Aedla Page 164 of 304


ORACLE

Trends Promoting Grid Computing


Numerous trends in the IT industry are moving enterprises towards grid computing.
Hardware Trends

Much of what makes grid computing possible today are the innovations surrounding
hardware. For example,
 Processors: New low-cost, high-volume Intel Itanium 2, Sun SPARC, and IBM
PowerPC 64-bit processors now deliver performance equal to or better than
processors used in high-end SMP servers.
 Servers: Blade server technology reduces the cost of hardware and increases the
density of servers, which further reduces expensive data center requirements.
These blade servers also come with remote management capabilities that make
it easy for data center administrators to manage these systems. Data centers
have started to leverage these technologies.
 Networked storage: Network Attached Storage (NAS) and Storage Area Networks
(SANs) enable sharing of storage across systems, further reducing costs.
 Network Interconnects: Gigabit Ethernet and Infiniband interconnect
technologies are driving down the cost of connecting clusters of servers.
Vlrtualization

Virtualization is the abstraction into a service of every physical and logical entity in a
grid. Virtualization is important because it enables grid components (such as storage,
processors, databases, application servers, and applications) to integrate tightly without
creating rigidity in the system.
For example, vendors such as Sun, HP, IBM, and Topspin are starting to deliver
hardware virtualization and provisioning technologies. These technologies allow you to
dynamically group and network a set of servers and storage components. You can also
dynamically move servers and storage components from one group to another. Some of
these technologies also allow dynamic loading and starting of the OS and applications
on these servers.
Software Trends

Linux runs very well on small computers (one to four CPUs) and provides the best price
for performance, making it ideal for a grid environment.
Linux continues to grow faster than any other OS. The economic advantage of blades
over SMP will cause blades to dominate in grid environments. Because Linux already
works well for blades, this will accelerate Linux growth. Because Linux has a price

By Subhash Reddy Aedla Page 165 of 304


ORACLE

advantage, which becomes even more important as the number of blades grows, Linux
adoption will further accelerate. Clusters of standard, low-cost blades naturally go well
with Linux, the standard inexpensive OS.
Hardware innovations can only be useful when the software running on them can
leverage those innovations. Software has started to leverage these hardware
innovations. One issue with software today is that it is designed to use the resources it is
provisioned, but it is not designed to give up resources it no longer needs. Oracle
provides software today - both Oracle Database and Oracle Application Server - that
leverage these hardware innovations. Oracle Database and Oracle Application Server
can utilize the resources they are provisioned and can easily relinquish resources they
no longer need.
Grid Momentum

In the technology industry, grid momentum is building. Major vendors, such as Oracle,
are already offering grid-enabling technology, and many others are preparing to. The
grid standards body, GGF, is in place and has the support of major technology vendors.
In IT organizations, grid momentum is also building. Grid technologies promise
increased utilization of existing hardware. Grids let you allocate your resources to meet
the needs of your business, instead of having islands of computing that are idle or
overloaded. As existing hardware needs to be replaced, blades offer the price for
performance. The economics are so compelling; enterprises have already started
leveraging blade servers for grid computing.
Fundamental Attributes of the Grid
All grids exhibit certain fundamental attributes. Enterprises can begin reaping the
benefits of grid computing by enhancing existing IT infrastructure with these attributes.
Virtualization at Every Layer

Virtualization enables grid components such as storage, processors, databases,


application servers, and applications to work together without creating rigidity and
brittleness in the system. Rather than making static ties that determine where a
database physically locates its data or which exact server the database runs on,
virtualization enables each component of the grid to react to changing circumstances
more quickly and to adapt to component failures without compromising performance of
the system as a whole.
Policy-Based Provisioning

Provisioning means allocating resources where they are needed. Once the resources are
virtualized, resources need to be dynamically allocated for various enterprise tasks

By Subhash Reddy Aedla Page 166 of 304


ORACLE

based on the changing business priorities. In the context of hardware resources,


hardware resources such as storage and servers need to be allocated to databases and
application servers. In the context of data, data needs to be allocated to where it is
needed.
Resource Pooling

Consolidation and pooling of resources is required for grids to achieve better utilization
of resources, a key contributor to lower costs. By pooling individual disks into storage
arrays and individual servers into blade farms, the grid runtime processes that
dynamically couple service consumers to service providers have more flexibility to
optimize the associations.

Oracle Database 10g: The Database for the Grid


Oracle Database 10g provides the first complete, integrated software infrastructure to
power grid computing. Oracle Database 10g leverages the grid-enabling hardware
innovations and has made it easy for you to install and configure the Oracle database on
these standardized modular hardware components.
Oracle Database 10g, both as the consumer of grid resources - servers and storage - and
as a provider of data, leverages the three fundamental attributes of grid computing.
Oracle Database 10g virtualizes the way the Oracle database uses the hardware
components - storage and servers. It automatically provisions clustered storage and
servers to different databases running in your grid. As a provider of data, Oracle
Database 10g provides technologies with which database administrators can pool,
virtualized, and provision data to grid users and applications.
In addition, an enterprise running on the grid imposes stringent operational
requirements in terms of security, high availability, self-reliance, and manageability.
Oracle Database 10g offers unrivaled operational benefits that simplify the management
and operations of your grid.
Configuring and Installing Oracle Database 10G on Standards-based Components
Oracle Database 10g makes it easy for you to run your database on a grid running on
standard low-cost modular hardware components - storage, blades, and interconnects.
Automatic Storage Management

Automatic Storage Management simplifies storage management for Oracle Databases.


By abstracting the details of storage management, Oracle improves data access
performance through sophisticated data provisioning, without requiring additional work
from DBAs. Instead of managing many database files, Oracle DB As manage only a small
number of disk groups. A disk group is a set of disk devices that Oracle manages as a

By Subhash Reddy Aedla Page 167 of 304


ORACLE

single, logical unit. An administrator can define a particular disk group as the default
disk group for a database, and Oracle automatically allocates storage for and creates or
deletes the files associated with the database object.
Automatic Storage Management also offers the benefits of storage technologies such as
RAID or Logical Volume Managers (LVMs). Oracle can balance I/O from multiple
databases across all of the devices in a disk group, and it implements striping and
mirroring to improve I/O performance and data reliability. In addition, Oracle can
reassign disks from node to node and cluster to cluster, automatically reconfiguring the
group. Because Automatic Storage Management is written to work exclusively with
Oracle, it achieves better performance than generalized storage virtualization solutions.
Portable Clusterware

Clusterware is the software that provides clustering services for communication


between servers in a cluster. New integrated clusterware in Oracle Database 10g makes
clustering easy by eliminating the need to purchase, install, configure, and support
third-party clusterware. There are no vendor-imposed limits on the size of a cluster.
Servers can be easily added to and dropped from an Oracle cluster with no downtime.
Oracle has also made it easy for you install this portable clusterware. With a single
install, you identify the nodes where you would like to install the portable clusterware
and Oracle Universal Installer installs portable clusterware on all those nodes.
Oracle has the only database technology to include clusterware for all operating
systems, which dramatically reduces the opportunities for failure in a clustered
environment.
High-speed InfiniBand Network Support

Oracle Database 10g has enhancements to provide you with better performance and
scalability with upcoming high-speed interconnects such as Infiniband. You can use
Infiniband for all network communications. It offers many benefits:
 Infiniband offers a tremendous performance improvement over Gigabit Ethernet
networks. The low latency and high-bandwidth of Infiniband makes it especially
useful as clusters interconnect.
 You use a single network infrastructure for your communication between
different servers and between servers and storage. This simplifies the cabling
requirements of your data center.
 With simplified network infrastructure, you use a single network backplane,
which makes network provisioning easier.

By Subhash Reddy Aedla Page 168 of 304


ORACLE

 With Oracle Database 10g, you can now use Infiniband for your application
server to database server communication, for server-to-server communication in
a clustered database, and for server to storage communication. This provides
you with all around performance improvement and flexibility in your data
center.
Easy Client Install

The easy client install feature simplifies deployment of applications in a grid. Clients of
the database only need to download or copy a very small subset of Oracle client files
and set an environment variable. These applications - OCI or JDBC applications - can
access a database on your grid. You no longer need to go through the install process on
the database client. This feature is especially useful for deployment of ISV applications.
ISVs can include these Oracle client files in their install process and customers need not
install Oracle clients separately. Additionally, in grid environments where client
machines are dynamically identified and configured, this feature simplifies the
installation and configuration of Oracle client software.
Easy Oracle Database Install

Oracle Database 10g has simplified the installation of the Oracle database. You can
install the Oracle database with a single CD. Oracle Universal Installer (OUI) can also
perform multi-node installs of the clustered Oracle database. During the install, you
identify the hostnames where you would like to install the Oracle database. OUI then
installs the Oracle Database software on all of those nodes. You can also decide to have
either a single shared image of the software or a separate image on each host machine.
Compute Resource Provisioning
The tenet of grid computing is the ability to dynamically align resources to your
changing priorities. Oracle Database 10g has numerous enhancements and new features
that make it easy for you to align your computing resources with your business needs.
Real Application Clusters (RAC)

Oracle Real Application Clusters (RAC) enables high utilization of a cluster of standard
low-cost modular servers such as blades. You can run a single Oracle database on a
cluster of blade servers. Applications running on RAC can dynamically leverage more
blades provisioned to them. Similarly, these applications can easily relinquish these
blades when they no longer need them. Conversely, commodity databases have
remarkably low utilization on commodity components. On the commodity databases,
you need to allocate for peak loads and allocate spares. You cannot add and remove
blades to the commodity databases without bringing down the entire system.

By Subhash Reddy Aedla Page 169 of 304


ORACLE

RAC, based on shared disk architecture, can grow and shrink on demand. This is not
possible with databases from other vendors as they are based on shared nothing
architecture, which does not offer this flexibility. With shared nothing, data is
partitioned artificially. When more blades are added, all the data needs to be
repartitioned to allocate data to the new blades. Similarly, when blades need to be
taken off, data needs to be repartitioned before taking off the blades.
Oracle Database 10g offers automatic workload management for services within a RAC
database. RAC automatically load balances connections as they are made across
instances hosting a service. In addition, using Resource Manager, you can specify
policies for resource allocation to services running within a RAC database. To meet
these policies, RAC will automatically provision database instances to these services.
Oracle Database 10g also offers a single-button addition and removal of servers to a
cluster. With the push of a button, you can now add a server to your cluster and
provision this server to the database. Oracle database automatically installs all the
required software - Portable Clusterware and Oracle Database software and starts an
Oracle database instance on it. Similarly, with the push of a button, you can remove a
server.
Resonance

A cluster is a user-defined set of servers that are clustered together using Oracle
Portable Clusterware. You run many databases on the same cluster and define your
service policies for these databases. Resonance will dynamically grow and shrink the
number of servers your individual databases are running on in this cluster to meet your
service-level objectives. This is done automatically without requiring any user
intervention.
Imagine you have a large cluster with many databases in it. If you had to manage it
manually, you would have to constantly monitor the load on each of those databases
and then you would have to manually shut down or bring up additional instances of
those databases. Your shut down command might take a very long time, as there might
be active sessions on the database instance. Oracle Database 10g does this for you. It
constantly monitors the load for you. When it needs to shut down an instance, it
automatically migrates active sessions to other active instances of the database.
Similarly, when it brings up an additional instance of a database, it automatically
balances the workload across all the instances of this database.
Oracle Scheduler

Oracle Database 10g introduces Oracle Scheduler, which provides you with many
advanced capabilities to schedule and perform business and IT tasks in your grid. You

By Subhash Reddy Aedla Page 170 of 304


ORACLE

can provision your workload within a database across time to get more efficient
resource utilization. First, you define your jobs, which can be stored procedures or
external jobs such as C or Java programs. Next, you define your schedule. Then you
assign jobs to schedules. You have the ability to define any arbitrarily complex schedule.
You can also group jobs into job classes to simplify management and prioritization of
jobs. Using Oracle Resource Manager, you can define your resource plans and assign
these resource plans to these job classes. You can also change these resource plans
across time. For example, you may consider the jobs to load a data warehouse to be
critical jobs during non-peak hours but not during peak hours.
Database Resource Manager

Resource Manager provisions resources to database users, applications, or services


within an Oracle database. It allows database administrators to limit the Oracle
database resources allocated to grid users, applications, or services. This ensures each
grid user, application, or service gets a fair share of the available computing resources.
Administrators define resource plans that allocate resources to various consumer
groups based on resource usage criteria such as CPU utilization or number of active
sessions. Each consumer group comprises one or more database users. Oracle Database
10g provides additional mappings for consumer groups based on user host machine,
application, OS username or service.
Information Provisioning
In addition to the provisioning of work across multiple nodes and the provisioning of
data across multiple disks, another type of provisioning happens within Oracle Database
10g-the provisioning of information itself. Information provisioning means getting
information delivered to users when they need it, regardless of where it resides on a
grid. To process information on any available resource, a grid must efficiently make
information available across distributed systems. There are essentially three ways to do
this: consolidate, share, and federate information.
Consolidating information in a single database makes it easy to provision information.
You use a single pool of resources where you run your database. This allows for more
efficient resource utilization. Since the database resources are pooled together, it does
not happen that one database is melting down while the other one is sitting idle. It
provides easy provisioning. You can now use Oracle Resource Manager to efficiently
provision Oracle database resources to various users and applications that are running
on this database.
If you cannot pool your resources and cannot consolidate your information in a single
database, you can share information to get more efficient resource utilization. Oracle

By Subhash Reddy Aedla Page 171 of 304


ORACLE

Database 10g features such as Oracle Transportable Tablespaces and Oracle Streams
make it easy for you to efficiently share data between different databases to share
processing of information across different resources.
For certain information, for example a terabyte database, that is infrequently accessed,
it is more efficient to leave the data in place. For this information, you can use Oracle
Database 10g's federated features such as distributed SQL, gateways, and materialized
views to get access to that data on demand.
Ultra Large Database Support

Oracle Database 10g now supports a single database with up to 8 exabytes (8 million
terabytes) of data. This virtually removes a limit on how large your consolidated
database can be. You can also store data in much larger files, thus decreasing the
number of files in large databases. Additionally, the Bigfile Tablespace simplifies the
management of datafiles in large databases, minimizes scalability issues related to
having a large number of datafiles, and simplifies management of storage utilizing such
features as Automatic Storage Management and Oracle Managed Files.
Oracle Transportable Tablespaces

It is not always possible to pool your hardware resources together. For example, you
might have geographically distributed hardware resources that you cannot cluster
efficiently. Or your data center limitations may prevent you from pooling the hardware
together. In these situations, Oracle Transportable Tablespaces offers a very efficient
way of sharing large subsets of data and then sharing processing on this data on
different hardware resources.
Oracle Transportable Tablespaces offer grid users an extremely fast mechanism to move
a subset of data from one Oracle database to another. It allows a set of tablespaces to
be unplugged from a database, moved or copied to another location, and then plugged
into another database. Unplugging or plugging a data file involves only reading or
loading a small amount of metadata. Transportable Tablespaces also supports
simultaneous mounting of read-only tablespaces by two or more databases.
Oracle Database 10g now supports heterogeneous transportable tablespaces. This
feature allows tablespaces to be unplugged, converted with RMAN if need be, and
transported across different platforms, for example, from Solaris or HP/uX to Linux.
For example, consider a financial application at a typical enterprise. It receives very light
usage during normal time, with a couple of inserts or updates every hour. But, during
quarter end, it needs considerably more resources for reporting. To accommodate these
increased demands, you could use the transportable tablespace feature to move the

By Subhash Reddy Aedla Page 172 of 304


ORACLE

data to a more powerful resource during quarter end, and perform your processing
there.
Oracle Streams

Some data needs to be shared as it is created or changed, rather than occasionally


shared in bulk. Oracle Streams can stream data between databases, nodes or blade
farms in a grid, and can keep two or more copies synchronized as updates are applied. It
also provides a unified framework for information sharing, combining message queuing,
replication, events, data warehouse loading, notifications and publish/subscribe into a
single technology.
If you take the example above, once you are done with reporting, either you can
throwaway the database or use Oracle Streams to keep the two databases in sync so
that you can do next quarter's reporting again using the second database. For this
purpose, you can define a schedule that fits your needs for synchronization. As an
example, you can synchronize every midnight or sync as the changes are happening.
Self-propelled Database

Oracle Database 10g offers a new self-propelled database feature. This feature utilizes
Oracle Transportable Tablespaces and Oracle Streams and offers you an easy way to
share processing across distributed hardware resources. In addition, it offers an efficient
way for migrating your applications to the grid.
With a single command, you can snap a set of tablespaces from one database, ship the
tablespace to another database, reformat the tablespace if the second database is on a
different OS, and plug this tablespace into the second database. During this time, there
might be changes happening at the first database. Oracle Streams would have already
started capturing those changes, which can later be synced with the second database.
All of this is done with a single command. If the second database is on a grid, what you
have just done is migrate your application to a grid with a single command. You can
later migrate all the applications running on the first database to the second database
by simply repointing the connection string to the second database.
Oracle Data Pump

With Oracle Database 10g, Oracle introduces a new data movement facility that greatly
improves performance when getting data into and out of a database. Oracle Data Pump
is a high-speed, parallel infrastructure that enables quick movement of data and
metadata from one database to another. This technology is the basis for Oracle's new
data movement utilities, Data Pump Export and Data Pump Import, which have greatly
enhanced performance over Oracle's original Export and Import.

By Subhash Reddy Aedla Page 173 of 304


ORACLE

When moving a transportable tablespace, Data Pump Export and Import are used to
handle the extraction and recreation of the metadata for that tablespace. Data Pump is
a flexible and fast way to unload entire databases or subsets of databases, and reload
them on the target platform.
Distributed SQL, Gateways, and Distributed Transactions

It is not always possible to either consolidate or share information. The limitations of


the data centers or geographical distribution of resources may prevent you from doing
so. It may also be because of security issues. You may not want the entire data set to be
visible to the users on the second database. Or it may not be efficient to move the data -
for example, you might have a oneterabyte data set that is infrequently accessed.
Oracle Database 10g offers an extremely strong federated technology that helps you in
these situations. With these technologies, you can leave data in place and access this
data on demand.
Oracle Distributed SQL allows grid users to efficiently access and integrate data stored in
multiple Oracle and non-Oracle databases. Gateways provide transparent remote data
access with Distributed SQL to grid users to run their applications against any other
database without making any code change to the applications. While integrating data
and managing transactions across multiple data stores, the Oracle database intelligently
optimizes the execution plans to access data in the most efficient manner. Oracle XA
capability allows grid users to coordinate distributed transactions across multiple
resources such as legacy applications and third-party application systems.
In addition, Oracle Database 10g also offers external tables and Bfiles features, that let
you keep your data on the file system while providing access to grid users via Oracle
database APIs. External tables provide you with SQL access to structured data in the
files. Bfiles provides read-only access to the unstructured data in the files.
Operational Benefits

The dynamic nature of the grid imposes stringent operational requirements on your grid
infrastructure. You would want the grid infrastructure to be self-reliant - it should be
able to tolerate system failures and adapt to changing business needs. You would like to
be able to control your grid environment in a more holistic manner rather than on a
component-by-component basis. Lastly, security is paramount in grid environments -
you would not like any unwanted exposure of your data and resources.
Self-Reliant Database

A truly responsive enterprise requires the grid infrastructure to self-manage, and to


learn and adapt to changing circumstances. Your grid infrastructure needs to be able to

By Subhash Reddy Aedla Page 174 of 304


ORACLE

tolerate the failures of individual components and to provide high availability in all
circumstances.
High Avallablllty

Oracle Database 10g brings the highest levels of reliability and availability to the grid.
You get the same levels of reliability and availability on standard, lowcost modular
hardware - servers and storage. Acknowledging that failures will happen, Oracle
Database 10g provides near instantaneous recovery from system faults, meeting the
most stringent service level agreements. Automatic Storage Management provides the
reliability and availability on low-cost standard storage. RAC provides the reliability and
availability on low-cost standard servers.
Oracle Database 10g provides robust features to protect from data errors and disasters.
The new flashback database feature provides the ability to recover a database to a
specific time to recover from human error. The recovery time is proportional to the time
duration to which it needs to go back. With this flash backup feature, database
administrators can now use low-cost standard disks for maintaining their backups.
Oracle Database 10g also includes tools to minimize planned downtime, critical for any
interactions in a 24x7 environment. The new rolIing upgrade feature enables online
application of patches to the database software. You don't need to bring down the
entire database to apply a patch. You can apply patches to the clustered database - one
instance at a time--thus keeping the database online while applying the patch.
Self.Managlng

With the new self-managing features, Oracle Database 10g has taken a giant leap
towards making the Oracle database self-reliant. Oracle Database 10g includes an
intelIigent database monitor that records data regarding all aspects of database
performance. Using this information, Oracle Database Automatic Memory Management
dynamically allocates memory to different components of the Oracle database.
Automatic health management automatically generates alerts regarding various aspects
of the database that simplify database monitoring for DBAs. Automatic Storage
Management, covered previously in this paper, provides automatic rebalancing and
provisioning of storage.
Oracle Enterprise Manager Grid Control

Even with the self-managing Oracle Database 10g, there are aspects of the enterprise
grid that administrators will want to manage and control. Oracle Enterprise Manager
Grid Control provides a single tool that can monitor and manage not only every Oracle
software element - Oracle Application Server 10g and Oracle Database 10g - in your grid

By Subhash Reddy Aedla Page 175 of 304


ORACLE

but also web applications via APM (Application Performance Management), hosts,
storage devices, and server load balancers. It is also extensible via an SDK so customers
can use it to monitor additional components that are not supported out-of-box.
Grid Control provides a simplified, centralized management framework for managing
enterprise resources and analyzing a grid's performance. With Grid Control, grid
administrators can manage the complete grid environment through a web browser
throughout the whole system's software lifecycle, front-to-back, from any location on
the network.
With Grid Control, administrators can launch and execute any number of integrated
Oracle database features such as Data Pump, Resource Manager, Scheduler,
Transportable Tablespaces, etc. Administrators can also monitor, diagnose, modify, and
tune multiple databases throughout the grid.
Grid Control views the availability and performance of the grid infrastructure as a
unified whole rather than as isolated storage units, databases, and application servers.
IT staff can group hardware nodes, databases, and application servers into single logical
entities and manage a group of targets as one unit. Administrators can also schedule
tasks on multiple systems at varying time intervals, share tasks with other
administrators, and group related services together to facilitate administration.
By executing jobs, enforcing standard policies, monitoring performance and automating
many other tasks across a group of targets instead of on many systems individually, Grid
Control enables IT staff to scale with a growing grid. Because of this feature, the
existence of many small computers in a grid infrastructure does not increase
management complexity.
Managing Security in the Grid

The dynamic nature of the grid makes security extremely important. Enterprises need to
ensure that their data is secure. Exactly the right set of users must have access to the
right set of data. At the same time, they need an easy way to manage security
throughout their enterprise. Oracle Database 10g makes it easy for enterprises to
manage their security needs in the grid.
Enterprise User Security

Enterprise User Security centralizes the management of user credentials and privileges
in a directory. This avoids the need to create the same user in multiple databases across
a grid. A directory-based user can authenticate and access all the databases that are
within an enterprise domain based on the credentials and privileges specified in the
directory.

By Subhash Reddy Aedla Page 176 of 304


ORACLE

With Oracle Database 10g, grid users have the ability to store an SSL Certificate in a
smart card, for roaming access to the grid. Oracle Database 10g also comes with Oracle
Certificate Authority that simplifies provisioning of certificates to grid users.
Virtual Private Database (VPD)

VPD provides server-enforced, fine-grained access control, and a secure application


context that can be used within a grid setting to enable multiple customers, partners, or
departments utilizing the same database to have secure access to mission-critical data.
VPD enables per-user and per-customer data access within a single database, with the
assurance of physical data separation. VPD is enabled by associating one or more
security policies with tables and views and now, in Oracle Database 10g. with table
columns.
Oracle Label Security

Oracle Label Security gives .administrators an out-of-the-box row-and now column-


level-security solution for controlling access to data based on its sensitivity, eliminating
the need to manually write such policies. Using the GUI tool Oracle Policy Manager,
administrators have the ability to quickly create and assign Oracle Label Security policies
to rows and columns within application tables. Moreover, Oracle Database 10g adds
integration of Oracle Label Security with Oracle Internet Directory (OlD), allowing
policies to be managed centrally within a dynamically changing grid setting.
Positioning for the Future
Grid technologies are evolving rapidly. Oracle assures the cost conscious enterprises
that their investments in Oracle today will be leveraged for future grid technologies.
Oracle possesses the right architecture and has its product directions fully aligned to
deliver future grid computing technologies.
Product Directions Aligned with Grid

Oracle product directions are aligned with the grid. Oracle Database 10g is the first
database designed for the grid. Oracle already supports more grid computing
technology than any of its competitors, as described in the previous sections. Your
investments in Oracle are well leveraged - you can incrementally adopt additional grid
computing technology as Oracle expands its technology stack.
Grid Standards Support

Oracle is committed to supporting industry standards. Oracle is working with the Global
Grid Forum to help define grid standards. Just as Oracle has
supported in its products, and is helping other standards, such as J2EE, Web Services,
Xquery, and SQL, Oracle intends to fully support grid standards. Often, the work of

By Subhash Reddy Aedla Page 177 of 304


ORACLE

various standards bodies overlap or various standards bodies develop complementary


technologies. By investing in Oracle Database 10g, you can leverage complementary
standards and intemperate with various standards and technologies.

By Subhash Reddy Aedla Page 178 of 304


ORACLE

Overview of PL/SQL
Advantages of PL/SQL
PL/SQL is a completely portable, high-performance transaction processing language that
offers the following advantages:
 Support for SQL
 Support for object-oriented programming
 Better performance
 Higher productivity
 Full portability
 Tight integration with Oracle
 Tight security

Tight Integration with SQL


The PL/SQL language is tightly integrated with SQL. You do not have to translate
between SQL and PL/SQL datatypes: a NUMBER or VARCHAR2 column in the database is
stored in a NUMBER or VARCHAR2 variable in PL/SQL. This integration saves you both
learning time and processing time. Special PL/SQL language features let you work with
table columns and rows without specifying the datatypes, saving on maintenance work
when the table definitions change.
Running a SQL query and processing the result set is as easy in PL/SQL as opening a text
file and processing each line in popular scripting languages.
Using PL/SQL to access metadata about database objects and handle database error
conditions, you can write utility programs for database administration that are reliable
and produce readable output about the success of each operation.
Many database features, such as triggers and object types, make use of PL/SQL. You can
write the bodies of triggers and methods for object types in PL/SQL.
Support for SQL
SQL has become the standard database language because it is flexible, powerful, and
easy to learn. A few English-like commands such as SELECT, INSERT, UPDATE, and DELETE
make it easy to manipulate the data stored in a relational database.
PL/SQL lets you use all the SQL data manipulation, cursor control, and transaction
control commands, as well as all the SQL functions, operators, and pseudocolumns. This
extensive SQL support lets you manipulate Oracle data flexibly and safely. Also, PL/SQL
fully supports SQL datatypes, reducing the need to convert data passed between your
applications and the database.

By Subhash Reddy Aedla Page 179 of 304


ORACLE

PL/SQL also supports dynamic SQL, a programming technique that makes your
applications more flexible and versatile. Your programs can build and process SQL data
definition, data control, and session control statements at run time, without knowing
details such as table names and WHERE clauses in advance.
Better Performance
Without PL/SQL, Oracle must process SQL statements one at a time. Programs that issue
many SQL statements require multiple calls to the database, resulting in significant
network and performance overhead.
With PL/SQL, an entire block of statements can be sent to Oracle at one time. This can
drastically reduce network traffic between the database and an application. As Figure 1-
1 shows, you can use PL/SQL blocks and subprograms to group SQL statements before
sending them to the database for execution. PL/SQL even has language features to
further speed up SQL statements that are issued inside a loop.
PL/SQL stored procedures are compiled once and stored in executable form, so
procedure calls are efficient. Because stored procedures execute in the database server,
a single call over the network can start a large job. This division of work reduces network
traffic and improves response times. Stored procedures are cached and shared among
users, which lowers memory requirements and invocation overhead.
Higher Productivity
PL/SQL extends tools such as Oracle Forms and Oracle Reports. With PL/SQL in these
tools, you can use familiar language constructs to build applications. For example, you
can use an entire PL/SQL block in an Oracle Forms trigger, instead of multiple trigger
steps, macros, or user exits.
PL/SQL is the same in all environments. Once you learn PL/SQL with one Oracle tool, you
can transfer your knowledge to other tools.
Full Portability
Applications written in PL/SQL can run on any operating system and platform where the
Oracle database runs. With PL/SQL, you can write portable program libraries and reuse
them in different environments.
Tight Security
PL/SQL stored procedures move application code from the client to the server, where
you can protect it from tampering, hide the internal details, and restrict who has access.
For example, you can grant users access to a procedure that updates a table, but not
grant them access to the table itself or to the text of the UPDATE statement.

By Subhash Reddy Aedla Page 180 of 304


ORACLE

Triggers written in PL/SQL can control or record changes to data, making sure that all
changes obey your business rules.
Support for Object-Oriented Programming
Object types are an ideal object-oriented modeling tool, which you can use to reduce
the cost and time required to build complex applications. Besides allowing you to create
software components that are modular, maintainable, and reusable, object types allow
different teams of programmers to develop software components concurrently.
By encapsulating operations with data, object types let you move data-maintenance
code out of SQL scripts and PL/SQL blocks into methods. Also, object types hide
implementation details, so that you can change the details without affecting client
programs.
In addition, object types allow for realistic data modeling. Complex real-world entities
and relationships map directly into object types. This direct mapping helps your
programs better reflect the world they are trying to simulate.

Understanding the Main Features of PL/SQL


PL/SQL combines the data-manipulating power of SQL with the processing power of
procedural languages.
You can control program flow with statements like IF and LOOP. As with other procedural
programming languages, you can declare variables, define procedures and functions,
and trap runtime errors.
PL/SQL lets you break complex problems down into easily understandable procedural
code, and reuse this code across multiple applications. When a problem can be solved
through plain SQL, you can issue SQL commands directly inside your PL/SQL programs,
without learning new APIs. PL/SQL's data types correspond with SQL's column types,
making it easy to interchange PL/SQL variables with data inside a table.
Block Structure
The basic units (procedures, functions, and anonymous blocks) that make up a PL/SQL
program are logical blocks, which can be nested inside one another.
A block groups related declarations and statements. You can place declarations close to
where they are used, even inside a large subprogram. The declarations are local to the
block and cease to exist when the block completes, helping to avoid cluttered
namespaces for variables and procedures.

By Subhash Reddy Aedla Page 181 of 304


ORACLE

As Figure 1-2 shows, a PL/SQL block has three parts: a declarative part, an executable
part, and an exception-handling part that deals with error conditions. Only the
executable part is required.
First comes the declarative part, where you define types, variables, and similar items.
These items are manipulated in the executable part. Exceptions raised during execution
can be dealt with in the exception-handling part.
Figure 1-2 Block Structure

You can nest blocks in the executable and exception-handling parts of a PL/SQL block or
subprogram but not in the declarative part. You can define local subprograms in the
declarative part of any block. You can call local subprograms only from the block in
which they are defined.
Variables and Constants
PL/SQL lets you declare constants and variables, then use them in SQL and procedural
statements anywhere an expression can be used. You must declare a constant or
variable before referencing it in any other statements.

Declaring Variables
Variables can have any SQL datatype, such as CHAR, DATE, or NUMBER, or a PL/SQL-only
datatype, such as BOOLEAN or PLS_INTEGER. For example, assume that you want to declare
a variable named part_no to hold 4-digit numbers and a variable named in_stock to hold
the Boolean value TRUE or FALSE. You declare these variables as follows:
part_no NUMBER(4);
in_stock BOOLEAN;

You can also declare nested tables, variable-size arrays (varrays for short), and records
using the TABLE, VARRAY, and RECORD composite datatypes.

By Subhash Reddy Aedla Page 182 of 304


ORACLE

Assigning Values to a Variable


You can assign values to a variable in three ways. The first way uses the assignment
operator (:=), a colon followed by an equal sign. You place the variable to the left of the
operator and an expression (which can include function calls) to the right. A few
examples follow:
tax := price * tax_rate;
valid_id := FALSE;
bonus := current_salary * 0.10;
wages := gross_pay(emp_id, st_hrs, ot_hrs) - deductions;
The second way to assign values to a variable is by selecting (or fetching) database
values into it. In the example below, you have Oracle compute a 10% bonus when you
select the salary of an employee. Now, you can use the variable bonus in another
computation or insert its value into a database table.
SELECT salary * 0.10 INTO bonus FROM employees WHERE employee_id = emp_id;
The third way to assign values to a variable is by passing it as an OUT or IN OUT parameter
to a subprogram, and doing the assignment inside the subprogram. The following
example passes a variable to a subprogram, and the subprogram updates the variable:
DECLARE
my_sal REAL(7,2);
PROCEDURE adjust_salary (emp_id INT, salary IN OUT REAL) IS ...
BEGIN
SELECT AVG(sal) INTO my_sal FROM emp;
adjust_salary(7788, my_sal); -- assigns a new value to my_sal

Declaring Constants
Declaring a constant is like declaring a variable except that you must add the keyword
CONSTANT and immediately assign a value to the constant. No further assignments to the
constant are allowed. The following example declares a constant:
credit_limit CONSTANT NUMBER := 5000.00;
Processing Queries with PL/SQL
Processing a SQL query with PL/SQL is like processing files with other languages. For
example, a Perl program opens a file, reads the file contents, processes each line, then
closes the file. In the same way, a PL/SQL program issues a query and processes the
rows from the result set:
FOR someone IN (SELECT * FROM employees)
LOOP

By Subhash Reddy Aedla Page 183 of 304


ORACLE

DBMS_OUTPUT.PUT_LINE('First name = ' || someone.first_name);


DBMS_OUTPUT.PUT_LINE('Last name = ' || someone.last_name);
END LOOP;
You can use a simple loop like the one shown here, or you can control the process
precisely by using individual statements to perform the query, retrieve data, and finish
processing.
Declaring PL/SQL Variables
As part of the declaration for each PL/SQL variable, you declare its datatype. Usually,
this datatype is one of the types shared between PL/SQL and SQL, such as NUMBER or
VARCHAR2(length). For easier maintenance of code that interacts with the database, you
can also use the special qualifiers %TYPE and %ROWTYPE to declare variables that hold
table columns or table rows.

%TYPE
The %TYPE attribute provides the datatype of a variable or database column. This is
particularly useful when declaring variables that will hold database values. For example,
assume there is a column named title in a table named books. To declare a variable
named my_title that has the same datatype as column title, use dot notation and the
%TYPE attribute, as follows:

my_title books.title%TYPE;
Declaring my_title with %TYPE has two advantages. First, you need not know the exact
datatype of title. Second, if you change the database definition of title (make it a longer
character string for example), the datatype of my_title changes accordingly at run time.

%ROWTYPE
In PL/SQL, records are used to group data. A record consists of a number of related
fields in which data values can be stored. The %ROWTYPE attribute provides a record type
that represents a row in a table. The record can store an entire row of data selected
from the table or fetched from a cursor or cursor variable.
Columns in a row and corresponding fields in a record have the same names and
datatypes. In the example below, you declare a record named dept_rec. Its fields have
the same names and datatypes as the columns in the dept table.
DECLARE
dept_rec dept%ROWTYPE; -- declare record variable
You use dot notation to reference fields, as the following example shows:

By Subhash Reddy Aedla Page 184 of 304


ORACLE

my_deptno := dept_rec.deptno;
If you declare a cursor that retrieves the last name, salary, hire date, and job title of an
employee, you can use %ROWTYPE to declare a record that stores the same information,
as follows:
DECLARE
CURSOR c1 IS
SELECT ename, sal, hiredate, job FROM emp;
emp_rec c1%ROWTYPE; -- declare record variable that represents
-- a row fetched from the emp table

When you execute the statement


FETCH c1 INTO emp_rec;

the value in the ename column of the emp table is assigned to the ename field of emp_rec,
the value in the sal column is assigned to the sal field, and so on.

Control Structures
Control structures are the most important PL/SQL extension to SQL. Not only does
PL/SQL let you manipulate Oracle data, it lets you process the data using conditional,
iterative, and sequential flow-of-control statements such as IF-THEN-ELSE, CASE, FOR-LOOP,
WHILE-LOOP, EXIT-WHEN, and GOTO.

Conditional Control
Often, it is necessary to take alternative actions depending on circumstances. The IF-
THEN-ELSE statement lets you execute a sequence of statements conditionally. The IF
clause checks a condition; the THEN clause defines what to do if the condition is true; the
ELSE clause defines what to do if the condition is false or null.

Consider the program below, which processes a bank transaction. Before allowing you
to withdraw $500 from account 3, it makes sure the account has sufficient funds to
cover the withdrawal. If the funds are available, the program debits the account.
Otherwise, the program inserts a record into an audit table.
-- available online in file 'examp2'
DECLARE
acct_balance NUMBER(11,2);

By Subhash Reddy Aedla Page 185 of 304


ORACLE

acct CONSTANT NUMBER(4) := 3;


debit_amt CONSTANT NUMBER(5,2) := 500.00;
BEGIN
SELECT bal INTO acct_balance FROM accounts
WHERE account_id = acct
FOR UPDATE OF bal;
IF acct_balance >= debit_amt THEN
UPDATE accounts SET bal = bal - debit_amt
WHERE account_id = acct;
ELSE
INSERT INTO temp VALUES
(acct, acct_balance, 'Insufficient funds');
-- insert account, current balance, and message
END IF;
COMMIT;
END;
To choose among several values or courses of action, you can use CASE constructs. The
CASE expression evaluates a condition and returns a value for each case. The case
statement evaluates a condition and performs an action (which might be an entire
PL/SQL block) for each case.
-- This CASE statement performs different actions based
-- on a set of conditional tests.
CASE
WHEN shape = 'square' THEN area := side * side;
WHEN shape = 'circle' THEN
BEGIN
area := pi * (radius * radius);
DBMS_OUTPUT.PUT_LINE('Value is not exact because pi is irrational.');
END;
WHEN shape = 'rectangle' THEN area := length * width;
ELSE
BEGIN
DBMS_OUTPUT.PUT_LINE('No formula to calculate area of a' || shape);
RAISE PROGRAM_ERROR;
END;
END CASE;

By Subhash Reddy Aedla Page 186 of 304


ORACLE

A sequence of statements that uses query results to select alternative actions is


common in database applications. Another common sequence inserts or deletes a row
only if an associated entry is found in another table. You can bundle these common
sequences into a PL/SQL block using conditional logic.

Iterative Control
LOOP statements let you execute a sequence of statements multiple times. You place the
keyword LOOP before the first statement in the sequence and the keywords END LOOP
after the last statement in the sequence. The following example shows the simplest kind
of loop, which repeats a sequence of statements continually:
LOOP
-- sequence of statements
END LOOP;
The FOR-LOOP statement lets you specify a range of integers, then execute a sequence of
statements once for each integer in the range. For example, the following loop inserts
500 numbers and their square roots into a database table:
FOR num IN 1..500 LOOP
INSERT INTO roots VALUES (num, SQRT(num));
END LOOP;

The WHILE-LOOP statement associates a condition with a sequence of statements. Before


each iteration of the loop, the condition is evaluated. If the condition is true, the
sequence of statements is executed, then control resumes at the top of the loop. If the
condition is false or null, the loop is bypassed and control passes to the next statement.
In the following example, you find the first employee who has a salary over $2500 and is
higher in the chain of command than employee 7499:
-- available online in file 'examp3'
DECLARE
salary emp.sal%TYPE := 0;
mgr_num emp.mgr%TYPE;
last_name emp.ename%TYPE;
starting_empno emp.empno%TYPE := 7499;
BEGIN
SELECT mgr INTO mgr_num FROM emp
WHERE empno = starting_empno;
WHILE salary <= 2500 LOOP
SELECT sal, mgr, ename INTO salary, mgr_num, last_name

By Subhash Reddy Aedla Page 187 of 304


ORACLE

FROM emp WHERE empno = mgr_num;


END LOOP;
INSERT INTO temp VALUES (NULL, salary, last_name);
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO temp VALUES (NULL, NULL, 'Not found');
COMMIT;
END;
The EXIT-WHEN statement lets you complete a loop if further processing is impossible or
undesirable. When the EXIT statement is encountered, the condition in the WHEN clause
is evaluated. If the condition is true, the loop completes and control passes to the next
statement. In the following example, the loop completes when the value of total exceeds
25,000:
LOOP
...
total := total + salary;
EXIT WHEN total > 25000; -- exit loop if condition is true
END LOOP;
-- control resumes here

Sequential Control
The GOTO statement lets you branch to a label unconditionally. The label, an undeclared
identifier enclosed by double angle brackets, must precede an executable statement or
a PL/SQL block. When executed, the GOTO statement transfers control to the labeled
statement or block, as the following example shows:
IF rating > 90 THEN
GOTO calc_raise; -- branch to label
END IF;
...
<<calc_raise>>
IF job_title = 'SALESMAN' THEN -- control resumes here
amount := commission * 0.25;

By Subhash Reddy Aedla Page 188 of 304


ORACLE

ELSE
amount := salary * 0.10;
END IF;

Writing Reusable PL/SQL Code


PL/SQL lets you break an application down into manageable, well-defined modules.
PL/SQL meets this need with program units, which include blocks, subprograms, and
packages. You can reuse program units by loading them into the database as triggers,
stored procedures, and stored functions.

Subprograms
PL/SQL has two types of subprograms called procedures and functions, which can take
parameters and be invoked (called). As the following example shows, a subprogram is
like a miniature program, beginning with a header followed by an optional declarative
part, an executable part, and an optional exception-handling part:
PROCEDURE award_bonus (emp_id NUMBER) IS
bonus REAL;
comm_missing EXCEPTION;
BEGIN -- executable part starts here
SELECT comm * 0.15 INTO bonus FROM emp WHERE empno = emp_id;
IF bonus IS NULL THEN
RAISE comm_missing;
ELSE
UPDATE payroll SET pay = pay + bonus WHERE empno = emp_id;
END IF;
EXCEPTION -- exception-handling part starts here
WHEN comm_missing THEN
...
END award_bonus;
When called, this procedure accepts an employee number. It uses the number to select
the employee's commission from a database table and, at the same time, compute a
15% bonus. Then, it checks the bonus amount. If the bonus is null, an exception is
raised; otherwise, the employee's payroll record is updated.

By Subhash Reddy Aedla Page 189 of 304


ORACLE

Packages
PL/SQL lets you bundle logically related types, variables, cursors, and subprograms into
a package, a database object that is a step above regular stored procedures. The
packages defines a simple, clear, interface to a set of related procedures and types.
Packages usually have two parts: a specification and a body. The specification defines
the application programming interface; it declares the types, constants, variables,
exceptions, cursors, and subprograms. The body fills in the SQL queries for cursors and
the code for subprograms.
The following example packages two employment procedures:
CREATE PACKAGE emp_actions AS -- package specification
PROCEDURE hire_employee (empno NUMBER, ename CHAR, ...);
PROCEDURE fire_employee (emp_id NUMBER);
END emp_actions;

CREATE PACKAGE BODY emp_actions AS -- package body


PROCEDURE hire_employee (empno NUMBER, ename CHAR, ...) IS
BEGIN
INSERT INTO emp VALUES (empno, ename, ...);
END hire_employee;
PROCEDURE fire_employee (emp_id NUMBER) IS
BEGIN
DELETE FROM emp WHERE empno = emp_id;
END fire_employee;
END emp_actions;
Applications that call these procedures only need to know the names and parameters
from the package spec. You can change the implementation details inside the package
body without affecting the calling applications.
Packages are stored in the database, where they can be shared by many applications.
Calling a packaged subprogram for the first time loads the whole package and caches it
in memory, saving on disk I/O for subsequent calls. Thus, packages enhance reuse and
improve performance in a multi-user, multi-application environment.
Data Abstraction
Data abstraction lets you work with the essential properties of data without being too
involved with details. Once you design a data structure, you can focus on designing
algorithms that manipulate the data structure.

By Subhash Reddy Aedla Page 190 of 304


ORACLE

Collections
PL/SQL collection types let you declare high-level datatypes similar to arrays, sets, and
hash tables found in other languages. In PL/SQL, array types are known as varrays (short
for variable-size arrays), set types are known as nested tables, and hash table types are
known as associative arrays. Each kind of collection is an ordered group of elements, all
of the same type. Each element has a unique subscript that determines its position in
the collection.
To reference an element, use subscript notation with parentheses. For example, the
following call references the fifth element in the nested table (of type Staff) returned by
function new_hires:
DECLARE
TYPE Staff IS TABLE OF Employee;
staffer Employee;
FUNCTION new_hires (hiredate DATE) RETURN Staff IS
BEGIN ... END;
BEGIN
staffer := new_hires('10-NOV-98')(5);
END;
Collections can be passed as parameters, so that subprograms can process arbitrary
numbers of elements.You can use collections to move data into and out of database
tables using high-performance language features known as bulk SQL.

Records
Records are composite data structures whose fields can have different datatypes. You
can use records to hold related items and pass them to subprograms with a single
parameter.
You can use the %ROWTYPE attribute to declare a record that represents a row in a table
or a row from a query result set, without specifying the names and types for the fields.
Consider the following example:
DECLARE
TYPE TimeRec IS RECORD (hours SMALLINT, minutes SMALLINT);
TYPE MeetingTyp IS RECORD (
date_held DATE,
duration TimeRec, -- nested record
location VARCHAR2(20),
purpose VARCHAR2(50));

By Subhash Reddy Aedla Page 191 of 304


ORACLE

Object Types
PL/SQL supports object-oriented programming through object types. An object type
encapsulates a data structure along with the functions and procedures needed to
manipulate the data. The variables that form the data structure are known as attributes.
The functions and procedures that manipulate the attributes are known as methods.
Object types reduce complexity by breaking down a large system into logical entities.
This lets you create software components that are modular, maintainable, and reusable.
Object-type definitions, and the code for the methods, are stored in the database.
Instances of these object types can be stored in tables or used as variables inside PL/SQL
code.
CREATE TYPE Bank_Account AS OBJECT (
acct_number INTEGER(5),
balance REAL,
status VARCHAR2(10),
MEMBER PROCEDURE open (amount IN REAL),
MEMBER PROCEDURE verify_acct (num IN INTEGER),
MEMBER PROCEDURE close (num IN INTEGER, amount OUT REAL),
MEMBER PROCEDURE deposit (num IN INTEGER, amount IN REAL),
MEMBER PROCEDURE withdraw (num IN INTEGER, amount IN REAL),
MEMBER FUNCTION curr_bal (num IN INTEGER) RETURN REAL
);
Error Handling
PL/SQL makes it easy to detect and process error conditions known as exceptions. When
an error occurs, an exception is raised: normal execution stops and control transfers to
special exception-handling code, which comes at the end of any PL/SQL block. Each
different exception is processed by a particular exception handler.
Predefined exceptions are raised automatically for certain common error conditions
involving variables or database operations. For example, if you try to divide a number by
zero, PL/SQL raises the predefined exception ZERO_DIVIDE automatically.
You can declare exceptions of your own, for conditions that you decide are errors, or to
correspond to database errors that normally result in ORA- error messages. When you
detect a user-defined error condition, you execute a RAISE statement. The following

By Subhash Reddy Aedla Page 192 of 304


ORACLE

example computes the bonus earned by a salesperson. The bonus is based on salary and
commission. If the commission is null, you raise the exception comm_missing.
DECLARE
comm_missing EXCEPTION; -- declare exception
BEGIN
IF commission IS NULL THEN
RAISE comm_missing; -- raise exception
END IF;
bonus := (salary * 0.10) + (commission * 0.15);
EXCEPTION
WHEN comm_missing THEN ... -- process the exception

PL/SQL Architecture
The PL/SQL compilation and run-time system is an engine that compiles and executes
PL/SQL blocks and subprograms. The engine can be installed in an Oracle server or in an
application development tool such as Oracle Forms or Oracle Reports.
In either environment, the PL/SQL engine accepts as input any valid PL/SQL block or
subprogram. Figure 1-3 shows the PL/SQL engine processing an anonymous block. The
PL/SQL engine executes procedural statements but sends SQL statements to the SQL
engine in the Oracle database.
Figure 1-3 PL/SQL Engine

In the Oracle Database Server


Typically, the Oracle database server processes PL/SQL blocks and subprograms.

By Subhash Reddy Aedla Page 193 of 304


ORACLE

Anonymous Blocks
Anonymous PL/SQL blocks can be submitted to interactive tools such as SQL*Plus and
Enterprise Manager, or embedded in an Oracle Precompiler or OCI program. At run
time, the program sends these blocks to the Oracle database, where they are compiled
and executed.

Stored Subprograms
Subprograms can be compiled and stored in an Oracle database, ready to be executed.
Once compiled, it is a schema object known as a stored procedure or stored function,
which can be referenced by any number of applications connected to that database.
Stored subprograms defined within a package are known as packaged subprograms.
Those defined independently are called standalone subprograms.
Subprograms nested inside other subprograms or within a PL/SQL block are known as
local subprograms, which cannot be referenced by other applications and exist only
inside the enclosing block.
Stored subprograms are the key to modular, reusable PL/SQL code. Wherever you might
use a JAR file in Java, a module in Perl, a shared library in C++, or a DLL in Visual Basic,
you should use PL/SQL stored procedures, stored functions, and packages.
You can call stored subprograms from a database trigger, another stored subprogram,
an Oracle Precompiler or OCI application, or interactively from SQL*Plus or Enterprise
Manager. You can also configure a web server so that the HTML for a web page is
generated by a stored subprogram, making it simple to provide a web interface for data
entry and report generation.
For example, you might call the standalone procedure create_dept from SQL*Plus as
follows:
SQL> CALL create_dept('FINANCE', 'NEW YORK');

Subprograms are stored in a compact compiled form. When called, they are loaded and
processed immediately. Subprograms take advantage of shared memory, so that only
one copy of a subprogram is loaded into memory for execution by multiple users.

Database Triggers
A database trigger is a stored subprogram associated with a database table, view, or
event. The trigger can be called once, when some event occurs, or many times, once for
each row affected by an INSERT, UPDATE, or DELETE statement. The trigger can be

By Subhash Reddy Aedla Page 194 of 304


ORACLE

called after the event, to record it or take some followup action. Or, the trigger can be
called before the event to prevent erroneous operations or fix new data so that it
conforms to business rules. For example, the following table-level trigger fires whenever
salaries in the emp table are updated:
CREATE TRIGGER audit_sal
AFTER UPDATE OF sal ON emp
FOR EACH ROW
BEGIN
INSERT INTO emp_audit VALUES ...
END;
The executable part of a trigger can contain procedural statements as well as SQL data
manipulation statements. Besides table-level triggers, there are instead-of triggers for
views and system-event triggers for schemas.
In Oracle Tools
An application development tool that contains the PL/SQL engine can process PL/SQL
blocks and subprograms. The tool passes the blocks to its local PL/SQL engine. The
engine executes all procedural statements inside the application and sends only SQL
statements to the database. Most of the work is done inside the application, not on the
database server. If the block contains no SQL statements, the application executes the
entire block. This is useful if your application can benefit from conditional and iterative
control.
Frequently, Oracle Forms applications use SQL statements to test the value of field
entries or to do simple computations. By using PL/SQL instead, you can avoid calls to the
database. You can also use PL/SQL functions to manipulate field entries.
Declarations
Your program stores values in variables and constants. As the program executes, the
values of variables can change, but the values of constants cannot.
You can declare variables and constants in the declarative part of any PL/SQL block,
subprogram, or package. Declarations allocate storage space for a value, specify its
datatype, and name the storage location so that you can reference it.
A couple of examples follow:
DECLARE
birthday DATE;
emp_count SMALLINT := 0;

By Subhash Reddy Aedla Page 195 of 304


ORACLE

The first declaration names a variable of type DATE. The second declaration names a
variable of type SMALLINT and uses the assignment operator to assign an initial value of
zero to the variable.
The next examples show that the expression following the assignment operator can be
arbitrarily complex and can refer to previously initialized variables:
DECLARE
pi REAL := 3.14159;
radius REAL := 1;
area REAL := pi * radius**2;
BEGIN
NULL;
END;
/
By default, variables are initialized to NULL, so it is redundant to include ":= NULL" in a
variable declaration.
To declare a constant, put the keyword CONSTANT before the type specifier:
DECLARE
credit_limit CONSTANT REAL := 5000.00;
max_days_in_year CONSTANT INTEGER := 366;
urban_legend CONSTANT BOOLEAN := FALSE;
BEGIN
NULL;
END;
/
This declaration names a constant of type REAL and assigns an unchangeable value of
5000 to the constant. A constant must be initialized in its declaration. Otherwise, you
get a compilation error.
Using DEFAULT
You can use the keyword DEFAULT instead of the assignment operator to initialize
variables. For example, the declaration
blood_type CHAR := 'O';
can be rewritten as follows:
blood_type CHAR DEFAULT 'O';
Use DEFAULT for variables that have a typical value. Use the assignment operator for
variables (such as counters and accumulators) that have no typical value. For example:

By Subhash Reddy Aedla Page 196 of 304


ORACLE

hours_worked INTEGER DEFAULT 40;


employee_count INTEGER := 0;
You can also use DEFAULT to initialize subprogram parameters, cursor parameters, and
fields in a user-defined record.
Using NOT NULL
Besides assigning an initial value, declarations can impose the NOT NULL constraint:
DECLARE
acct_id INTEGER(4) NOT NULL := 9999;
You cannot assign nulls to a variable defined as NOT NULL. If you try, PL/SQL raises the
predefined exception VALUE_ERROR.
The NOT NULL constraint must be followed by an initialization clause.
PL/SQL provide subtypes NATURALN and POSITIVEN that are predefined as NOT NULL. You
can omit the NOT NULL constraint when declaring variables of these types, and you must
include an initialization clause.
Using the %TYPE Attribute
The %TYPE attribute provides the datatype of a variable or database column. In the
following example, %TYPE provides the datatype of a variable:
DECLARE
credit NUMBER(7,2);
debit credit%TYPE;
name VARCHAR2(20) := 'JoHn SmItH';
-- If we increase the length of NAME, the other variables
-- become longer too.
upper_name name%TYPE := UPPER(name);
lower_name name%TYPE := LOWER(name);
init_name name%TYPE := INITCAP(name);
BEGIN
NULL;
END;
/
Variables declared using %TYPE are treated like those declared using a datatype specifier.
For example, given the previous declarations, PL/SQL treats debit like a REAL(7,2) variable.
A %TYPE declaration can also include an initialization clause.

By Subhash Reddy Aedla Page 197 of 304


ORACLE

The %TYPE attribute is particularly useful when declaring variables that refer to database
columns. You can reference a table and column, or you can reference an owner, table,
and column, as in
DECLARE
-- If the length of the column ever changes, this code
-- will use the new length automatically.
the_trigger user_triggers.trigger_name%TYPE;
BEGIN
NULL;
END;
/
When you use table_name.column_name.TYPE to declare a variable, you do not need to
know the actual datatype, and attributes such as precision, scale, and length. If the
database definition of the column changes, the datatype of the variable changes
accordingly at run time.
%TYPE variables do not inherit the NOT NULL column constraint. In the next example, even
though the database column employee_id is defined as NOT NULL, you can assign a null to
the variable my_empno:
DECLARE
my_empno employees.employee_id%TYPE;
BEGIN
my_empno := NULL; -- this works
END;
/
Using the %ROWTYPE Attribute
The %ROWTYPE attribute provides a record type that represents a row in a table (or view).
The record can store an entire row of data selected from the table, or fetched from a
cursor or strongly typed cursor variable:
DECLARE
-- %ROWTYPE can include all the columns in a table...
emp_rec employees%ROWTYPE;
-- ...or a subset of the columns, based on a cursor.
CURSOR c1 IS
SELECT department_id, department_name FROM departments;

By Subhash Reddy Aedla Page 198 of 304


ORACLE

dept_rec c1%ROWTYPE;
-- Could even make a %ROWTYPE with columns from multiple tables.
CURSOR c2 IS
SELECT employee_id, email, employees.manager_id, location_id
FROM employees, departments
WHERE employees.department_id = departments.department_id;
join_rec c2%ROWTYPE;
BEGIN
-- We know EMP_REC can hold a row from the EMPLOYEES table.
SELECT * INTO emp_rec FROM employees WHERE ROWNUM < 2;
-- We can refer to the fields of EMP_REC using column names
-- from the EMPLOYEES table.
IF emp_rec.department_id = 20 AND emp_rec.last_name = 'JOHNSON' THEN
emp_rec.salary := emp_rec.salary * 1.15;
END IF;
END;
/
Columns in a row and corresponding fields in a record have the same names and
datatypes. However, fields in a %ROWTYPE record do not inherit the NOT NULL column
constraint.

Aggregate Assignment
Although a %ROWTYPE declaration cannot include an initialization clause, there are ways
to assign values to all fields in a record at once. You can assign one record to another if
their declarations refer to the same table or cursor. For example, the following
assignment is allowed:
DECLARE
dept_rec1 departments%ROWTYPE;
dept_rec2 departments%ROWTYPE;
CURSOR c1 IS SELECT department_id, location_id FROM departments;
dept_rec3 c1%ROWTYPE;
BEGIN

By Subhash Reddy Aedla Page 199 of 304


ORACLE

dept_rec1 := dept_rec2; -- allowed


-- dept_rec2 refers to a table, dept_rec3 refers to a cursor
-- dept_rec2 := dept_rec3; -- not allowed
END;
/
You can assign a list of column values to a record by using the SELECT or FETCH statement,
as the following example shows. The column names must appear in the order in which
they were defined by the CREATE TABLE or CREATE VIEW statement.
DECLARE
dept_rec departments%ROWTYPE;
BEGIN
SELECT * INTO dept_rec FROM departments
WHERE department_id = 30 and ROWNUM < 2;
END;
/
However, there is no constructor for a record type, so you cannot assign a list of column
values to a record by using an assignment statement.

Using Aliases
Select-list items fetched from a cursor associated with %ROWTYPE must have simple
names or, if they are expressions, must have aliases. The following example uses an alias
called complete_name to represent the concatenation of two columns:
BEGIN
-- We assign an alias (COMPLETE_NAME) to the expression value, because
-- it has no column name.
FOR item IN
(
SELECT first_name || ' ' || last_name complete_name
FROM employees WHERE ROWNUM < 11
)
LOOP
-- Now we can refer to the field in the record using this alias.
dbms_output.put_line('Employee name: ' || item.complete_name);
END LOOP;
END;
/

By Subhash Reddy Aedla Page 200 of 304


ORACLE

Restrictions on Declarations
PL/SQL does not allow forward references. You must declare a variable or constant
before referencing it in other statements, including other declarative statements.
PL/SQL does allow the forward declaration of subprograms
Some languages allow you to declare a list of variables that have the same datatype.
PL/SQL does not allow this. You must declare each variable separately:
DECLARE
-- Multiple declarations not allowed.
-- i, j, k, l SMALLINT;
-- Instead, declare each separately.
i SMALLINT;
j SMALLINT;
-- To save space, you can declare more than one on a line.
k SMALLINT; l SMALLINT;
BEGIN
NULL;
END;
/

Testing Conditions: IF and CASE Statements


The IF statement executes a sequence of statements depending on the value of a
condition. There are three forms of IF statements: IF-THEN, IF-THEN-ELSE, and IF-THEN-ELSIF.
The CASE statement is a compact way to evaluate a single condition and choose between
many alternative actions. It makes sense to use CASE when there are three or more
alternatives to choose from.
Using the IF-THEN Statement
The simplest form of IF statement associates a condition with a sequence of statements
enclosed by the keywords THEN and END IF (not ENDIF):
IF condition THEN
sequence_of_statements
END IF;
The sequence of statements is executed only if the condition is true. If the condition is
false or null, the IF statement does nothing. In either case, control passes to the next
statement.
IF sales > quota THEN
compute_bonus(empid);

By Subhash Reddy Aedla Page 201 of 304


ORACLE

UPDATE payroll SET pay = pay + bonus WHERE empno = emp_id;


END IF;
You can place brief IF statements on a single line:
IF x > y THEN high := x; END IF;
Using the IF-THEN-ELSE Statement
The second form of IF statement adds the keyword ELSE followed by an alternative
sequence of statements:
IF condition THEN
sequence_of_statements1
ELSE
sequence_of_statements2
END IF;
The statements in the ELSE clause are executed only if the condition is false or null. The
IF-THEN-ELSE statement ensures that one or the other sequence of statements is
executed. In the following example, the first UPDATE statement is executed when the
condition is true, and the second UPDATE statement is executed when the condition is
false or null:
IF trans_type = 'CR' THEN
UPDATE accounts SET balance = balance + credit WHERE ...
ELSE
UPDATE accounts SET balance = balance - debit WHERE ...
END IF;
IF statements can be nested:
IF trans_type = 'CR' THEN
UPDATE accounts SET balance = balance + credit WHERE ...
ELSE
IF new_balance >= minimum_balance THEN
UPDATE accounts SET balance = balance - debit WHERE ...
ELSE
RAISE insufficient_funds;
END IF;
END IF;
Using the IF-THEN-ELSIF Statement
Sometimes you want to choose between several alternatives. You can use the keyword
ELSIF (not ELSEIF or ELSE IF) to introduce additional conditions:

By Subhash Reddy Aedla Page 202 of 304


ORACLE

IF condition1 THEN
sequence_of_statements1
ELSIF condition2 THEN
sequence_of_statements2
ELSE
sequence_of_statements3
END IF;
If the first condition is false or null, the ELSIF clause tests another condition. An IF
statement can have any number of ELSIF clauses; the final ELSE clause is optional.
Conditions are evaluated one by one from top to bottom. If any condition is true, its
associated sequence of statements is executed and control passes to the next
statement. If all conditions are false or null, the sequence in the ELSE clause is executed.
Consider the following example:
BEGIN
IF sales > 50000 THEN
bonus := 1500;
ELSIF sales > 35000 THEN
bonus := 500;
ELSE
bonus := 100;
END IF;
INSERT INTO payroll VALUES (emp_id, bonus, ...);
END;
If the value of sales is larger than 50000, the first and second conditions are true.
Nevertheless, bonus is assigned the proper value of 1500 because the second condition is
never tested. When the first condition is true, its associated statement is executed and
control passes to the INSERT statement.
Using the CASE Statement
Like the IF statement, the CASE statement selects one sequence of statements to
execute. However, to select the sequence, the CASE statement uses a selector rather
than multiple Boolean expressions. (Recall from Chapter 2 that a selector is an
expression whose value is used to select one of several alternatives.) To compare the IF
and CASE statements, consider the following code that outputs descriptions of school
grades:
IF grade = 'A' THEN
dbms_output.put_line('Excellent');
ELSIF grade = 'B' THEN

By Subhash Reddy Aedla Page 203 of 304


ORACLE

dbms_output.put_line('Very Good');
ELSIF grade = 'C' THEN
dbms_output.put_line('Good');
ELSIF grade = 'D' THEN
dbms_output. put_line('Fair');
ELSIF grade = 'F' THEN
dbms_output.put_line('Poor');
ELSE
dbms_output.put_line('No such grade');
END IF;

Notice the five Boolean expressions. In each instance, we test whether the same
variable, grade, is equal to one of five values: 'A', 'B', 'C', 'D', or 'F'. Let us rewrite the
preceding code using the CASE statement, as follows:
CASE grade
WHEN 'A' THEN dbms_output.put_line('Excellent');
WHEN 'B' THEN dbms_output.put_line('Very Good');
WHEN 'C' THEN dbms_output.put_line('Good');
WHEN 'D' THEN dbms_output.put_line('Fair');
WHEN 'F' THEN dbms_output.put_line('Poor');
ELSE dbms_output.put_line('No such grade');
END CASE;

The CASE statement is more readable and more efficient. When possible, rewrite lengthy
IF-THEN-ELSIF statements as CASE statements.

The CASE statement begins with the keyword CASE. The keyword is followed by a
selector, which is the variable grade in the last example. The selector expression can be
arbitrarily complex. For example, it can contain function calls. Usually, however, it
consists of a single variable. The selector expression is evaluated only once. The value it
yields can have any PL/SQL datatype other than BLOB, BFILE, an object type, a PL/SQL
record, an index-by-table, a varray, or a nested table.
The selector is followed by one or more WHEN clauses, which are checked sequentially.
The value of the selector determines which clause is executed. If the value of the
selector equals the value of a WHEN-clause expression, that WHEN clause is executed. For
instance, in the last example, if grade equals 'C', the program outputs 'Good'. Execution

By Subhash Reddy Aedla Page 204 of 304


ORACLE

never falls through; if any WHEN clause is executed, control passes to the next
statement.
The ELSE clause works similarly to the ELSE clause in an IF statement. In the last example,
if the grade is not one of the choices covered by a WHEN clause, the ELSE clause is
selected, and the phrase 'No such grade' is output. The ELSE clause is optional. However, if
you omit the ELSE clause, PL/SQL adds the following implicit ELSE clause:
ELSE RAISE CASE_NOT_FOUND;
There is always a default action, even when you omit the ELSE clause. If the CASE
statement does not match any of the WHEN clauses and you omit the ELSE clause, PL/SQL
raises the predefined exception CASE_NOT_FOUND.
The keywords END CASE terminate the CASE statement. These two keywords must be
separated by a space. The CASE statement has the following form:
[<<label_name>>]
CASE selector
WHEN expression1 THEN sequence_of_statements1;
WHEN expression2 THEN sequence_of_statements2;
...
WHEN expressionN THEN sequence_of_statementsN;
[ELSE sequence_of_statementsN+1;]
END CASE [label_name];

Like PL/SQL blocks, CASE statements can be labeled. The label, an undeclared identifier
enclosed by double angle brackets, must appear at the beginning of the CASE statement.
Optionally, the label name can also appear at the end of the CASE statement.
Exceptions raised during the execution of a CASE statement are handled in the usual
way. That is, normal execution stops and control transfers to the exception-handling
part of your PL/SQL block or subprogram.
An alternative to the CASEstatement is the CASE expression, where each WHEN clause is
an expression. For details, see "CASE Expressions".

Searched CASE Statement


PL/SQL also provides a searched CASE statement, which has the form:

By Subhash Reddy Aedla Page 205 of 304


ORACLE

[<<label_name>>]
CASE
WHEN search_condition1 THEN sequence_of_statements1;
WHEN search_condition2 THEN sequence_of_statements2;
...
WHEN search_conditionN THEN sequence_of_statementsN;
[ELSE sequence_of_statementsN+1;]
END CASE [label_name];

The searched CASE statement has no selector. Also, its WHEN clauses contain search
conditions that yield a Boolean value, not expressions that can yield a value of any type.
An example follows:
CASE
WHEN grade = 'A' THEN dbms_output.put_line('Excellent');
WHEN grade = 'B' THEN dbms_output.put_line('Very Good');
WHEN grade = 'C' THEN dbms_output.put_line('Good');
WHEN grade = 'D' THEN dbms_output.put_line('Fair');
WHEN grade = 'F' THEN dbms_output.put_line('Poor');
ELSE dbms_output.put_line('No such grade');
END CASE;

The search conditions are evaluated sequentially. The Boolean value of each search
condition determines which WHEN clause is executed. If a search condition yields TRUE,
its WHEN clause is executed. If any WHEN clause is executed, control passes to the next
statement, so subsequent search conditions are not evaluated.
If none of the search conditions yields TRUE, the ELSE clause is executed. The ELSE clause
is optional. However, if you omit the ELSE clause, PL/SQL adds the following implicit ELSE
clause:
ELSE RAISE CASE_NOT_FOUND;

By Subhash Reddy Aedla Page 206 of 304


ORACLE

Exceptions raised during the execution of a searched CASE statement are handled in the
usual way. That is, normal execution stops and control transfers to the exception-
handling part of your PL/SQL block or subprogram.
Guidelines for PL/SQL Conditional Statements
Avoid clumsy IF statements like those in the following example:
IF new_balance < minimum_balance THEN
overdrawn := TRUE;
ELSE
overdrawn := FALSE;
END IF;
...
IF overdrawn = TRUE THEN
RAISE insufficient_funds;
END IF;

The value of a Boolean expression can be assigned directly to a Boolean variable. You
can replace the first IF statement with a simple assignment:
overdrawn := new_balance < minimum_balance;

A Boolean variable is itself either true or false. You can simplify the condition in the
second IF statement:
IF overdrawn THEN ...

When possible, use the ELSIF clause instead of nested IF statements. Your code will be
easier to read and understand. Compare the following IF statements:
IF condition1 THEN | IF condition1 THEN
statement1; | statement1;
ELSE | ELSIF condition2 THEN
IF condition2 THEN | statement2;
statement2; | ELSIF condition3 THEN

By Subhash Reddy Aedla Page 207 of 304


ORACLE

ELSE | statement3;
IF condition3 THEN | END IF;
statement3; |
END IF; |
END IF; |
END IF; |

These statements are logically equivalent, but the second statement makes the logic
clearer.
To compare a single expression to multiple values, you can simplify the logic by using a
single CASE statement instead of an IF with several ELSIF clauses.

Controlling Loop Iterations: LOOP and EXIT Statements


LOOP statements execute a sequence of statements multiple times. There are three
forms of LOOP statements: LOOP, WHILE-LOOP, and FOR-LOOP.
Using the LOOP Statement
The simplest form of LOOP statement is the basic loop, which encloses a sequence of
statements between the keywords LOOP and END LOOP, as follows:
LOOP
sequence_of_statements
END LOOP;

With each iteration of the loop, the sequence of statements is executed, then control
resumes at the top of the loop. You use an EXIT statement to stop looping and prevent
an infinite loop. You can place one or more EXIT statements anywhere inside a loop, but
not outside a loop. There are two forms of EXIT statements: EXIT and EXIT-WHEN.
Using the EXIT Statement
The EXIT statement forces a loop to complete unconditionally. When an EXIT statement is
encountered, the loop completes immediately and control passes to the next
statement:
LOOP

By Subhash Reddy Aedla Page 208 of 304


ORACLE

IF credit_rating < 3 THEN


EXIT; -- exit loop immediately
END IF;
END LOOP;
-- control resumes here

Remember, the EXIT statement must be placed inside a loop. To complete a PL/SQL block
before its normal end is reached, you can use the RETURN statement. For more
information, see "Using the RETURN Statement".
Using the EXIT-WHEN Statement
The EXIT-WHEN statement lets a loop complete conditionally. When the EXIT statement is
encountered, the condition in the WHEN clause is evaluated. If the condition is true, the
loop completes and control passes to the next statement after the loop:
LOOP
FETCH c1 INTO ...
EXIT WHEN c1%NOTFOUND; -- exit loop if condition is true
...
END LOOP;
CLOSE c1;

Until the condition is true, the loop cannot complete. A statement inside the loop must
change the value of the condition. In the previous example, if the FETCH statement
returns a row, the condition is false. When the FETCH statement fails to return a row, the
condition is true, the loop completes, and control passes to the CLOSE statement.
The EXIT-WHEN statement replaces a simple IF statement. For example, compare the
following statements:
IF count > 100 THEN | EXIT WHEN count > 100;
EXIT; |
END IF; |

By Subhash Reddy Aedla Page 209 of 304


ORACLE

These statements are logically equivalent, but the EXIT-WHEN statement is easier to read
and understand.
Labeling a PL/SQL Loop
Like PL/SQL blocks, loops can be labeled. The label, an undeclared identifier enclosed by
double angle brackets, must appear at the beginning of the LOOP statement, as follows:
<<label_name>>
LOOP
sequence_of_statements
END LOOP;

Optionally, the label name can also appear at the end of the LOOP statement, as the
following example shows:
<<my_loop>>
LOOP
...
END LOOP my_loop;

When you nest labeled loops, use ending label names to improve readability.
With either form of EXIT statement, you can complete not only the current loop, but any
enclosing loop. Simply label the enclosing loop that you want to complete. Then, use the
label in an EXIT statement, as follows:
<<outer>>
LOOP
...
LOOP
...
EXIT outer WHEN ... -- exit both loops
END LOOP;
...
END LOOP outer;

By Subhash Reddy Aedla Page 210 of 304


ORACLE

Every enclosing loop up to and including the labeled loop is exited.


Using the WHILE-LOOP Statement
The WHILE-LOOP statement executes the statements in the loop body as long as a
condition is true:
WHILE condition LOOP
sequence_of_statements
END LOOP;

Before each iteration of the loop, the condition is evaluated. If it is true, the sequence of
statements is executed, then control resumes at the top of the loop. If it is false or null,
the loop is skipped and control passes to the next statement:
WHILE total <= 25000 LOOP
SELECT sal INTO salary FROM emp WHERE ...
total := total + salary;
END LOOP;

The number of iterations depends on the condition and is unknown until the loop
completes. The condition is tested at the top of the loop, so the sequence might execute
zero times. In the last example, if the initial value of total is larger than 25000, the
condition is false and the loop is skipped.
Some languages have a LOOP UNTIL or REPEAT UNTIL structure, which tests the condition at
the bottom of the loop instead of at the top, so that the sequence of statements is
executed at least once. The equivalent in PL/SQL would be:
LOOP
sequence_of_statements
EXIT WHEN boolean_expression;
END LOOP;

To ensure that a WHILE loop executes at least once, use an initialized Boolean variable in
the condition, as follows:

By Subhash Reddy Aedla Page 211 of 304


ORACLE

done := FALSE;
WHILE NOT done LOOP
sequence_of_statements
done := boolean_expression;
END LOOP;

A statement inside the loop must assign a new value to the Boolean variable to avoid an
infinite loop.
Using the FOR-LOOP Statement
Simple FOR loops iterate over a specified range of integers. The number of iterations is
known before the loop is entered. A double dot (..) serves as the range operator:
FOR counter IN [REVERSE] lower_bound..higher_bound LOOP
sequence_of_statements
END LOOP;

The range is evaluated when the FOR loop is first entered and is never re-evaluated.
As the next example shows, the sequence of statements is executed once for each
integer in the range. After each iteration, the loop counter is incremented.
FOR i IN 1..3 LOOP -- assign the values 1,2,3 to i
sequence_of_statements -- executes three times
END LOOP;

If the lower bound equals the higher bound, the loop body is executed once:
FOR i IN 3..3 LOOP -- assign the value 3 to i
sequence_of_statements -- executes one time
END LOOP;

By default, iteration proceeds upward from the lower bound to the higher bound. If you
use the keyword REVERSE, iteration proceeds downward from the higher bound to the

By Subhash Reddy Aedla Page 212 of 304


ORACLE

lower bound. After each iteration, the loop counter is decremented. You still write the
range bounds in ascending (not descending) order.
FOR i IN REVERSE 1..3 LOOP -- assign the values 3,2,1 to i
sequence_of_statements -- executes three times
END LOOP;

Inside a FOR loop, the counter can be read but cannot be changed:
FOR ctr IN 1..10 LOOP
IF NOT finished THEN
INSERT INTO ... VALUES (ctr, ...); -- OK
factor := ctr * 2; -- OK
ELSE
ctr := 10; -- not allowed
END IF;
END LOOP;

How PL/SQL Loops Iterate


The bounds of a loop range can be literals, variables, or expressions but must evaluate
to numbers. Otherwise, PL/SQL raises the predefined exception VALUE_ERROR. The lower
bound need not be 1, but the loop counter increment or decrement must be 1.
j IN -5..5
k IN REVERSE first..last
step IN 0..TRUNC(high/low) * 2

Internally, PL/SQL assigns the values of the bounds to temporary PLS_INTEGER variables,
and, if necessary, rounds the values to the nearest integer. The magnitude range of a
PLS_INTEGER is -2**31 .. 2**31. If a bound evaluates to a number outside that range, you
get a numeric overflow error when PL/SQL attempts the assignment.
Some languages provide a STEP clause, which lets you specify a different increment (5
instead of 1 for example). PL/SQL has no such structure, but you can easily build one.
Inside the FOR loop, simply multiply each reference to the loop counter by the new
increment. In the following example, you assign today's date to elements 5, 10, and 15
of an index-by table:
DECLARE

By Subhash Reddy Aedla Page 213 of 304


ORACLE

TYPE DateList IS TABLE OF DATE INDEX BY BINARY_INTEGER;


dates DateList;
k CONSTANT INTEGER := 5; -- set new increment
BEGIN
FOR j IN 1..3 LOOP
dates(j*k) := SYSDATE; -- multiply loop counter by increment
END LOOP;
...
END;

Dynamic Ranges for Loop Bounds


PL/SQL lets you specify the loop range at run time by using variables for bounds:
SELECT COUNT(empno) INTO emp_count FROM emp;
FOR i IN 1..emp_count LOOP
...
END LOOP;

If the lower bound of a loop range evaluates to a larger integer than the upper bound,
the loop body is not executed and control passes to the next statement:
-- limit becomes 1
FOR i IN 2..limit LOOP
sequence_of_statements -- executes zero times
END LOOP;
-- control passes here

Scope of the Loop Counter Variable


The loop counter is defined only within the loop. You cannot reference that variable
name outside the loop. After the loop exits, the loop counter is undefined:
FOR ctr IN 1..10 LOOP
...
END LOOP;
sum := ctr - 1; -- not allowed

By Subhash Reddy Aedla Page 214 of 304


ORACLE

You do not need to declare the loop counter because it is implicitly declared as a local
variable of type INTEGER. It is safest not to use the name of an existing variable, because
the local declaration hides any global declaration:
DECLARE
ctr INTEGER := 3;
BEGIN
...
FOR ctr IN 1..25 LOOP
...
IF ctr > 10 THEN ... -- Refers to loop counter
END LOOP;
-- After the loop, ctr refers to the original variable with value 3.
END;

To reference the global variable in this example, you must use a label and dot notation,
as follows:
<<main>>
DECLARE
ctr INTEGER;
...
BEGIN
...
FOR ctr IN 1..25 LOOP
...
IF main.ctr > 10 THEN -- refers to global variable
...
END IF;
END LOOP;
END main;

The same scope rules apply to nested FOR loops. Consider the example below. Both loop
counters have the same name. To reference the outer loop counter from the inner loop,
you use a label and dot notation:
<<outer>>
FOR step IN 1..25 LOOP
FOR step IN 1..10 LOOP
...

By Subhash Reddy Aedla Page 215 of 304


ORACLE

IF outer.step > 15 THEN ...


END LOOP;
END LOOP outer;

Using the EXIT Statement in a FOR Loop


The EXIT statement lets a FOR loop complete early. For example, the following loop
normally executes ten times, but as soon as the FETCH statement fails to return a row,
the loop completes no matter how many times it has executed:
FOR j IN 1..10 LOOP
FETCH c1 INTO emp_rec;
EXIT WHEN c1%NOTFOUND;
...
END LOOP;

Suppose you must exit early from a nested FOR loop. To complete not only the current
loop, but also any enclosing loop, label the enclosing loop and use the label in an EXIT
statement:
<<outer>>
FOR i IN 1..5 LOOP
...
FOR j IN 1..10 LOOP
FETCH c1 INTO emp_rec;
EXIT outer WHEN c1%NOTFOUND; -- exit both FOR loops
...
END LOOP;
END LOOP outer;
-- control passes here
Sequential Control: GOTO and NULL Statements
Unlike the IF and LOOP statements, the GOTO and NULL statements are not crucial to
PL/SQL programming. The GOTO statement is seldom needed. Occasionally, it can
simplify logic enough to warrant its use. The NULL statement can improve readability by
making the meaning and action of conditional statements clear.
Overuse of GOTO statements can result in code that is hard to understand and maintain.
Use GOTO statements sparingly. For example, to branch from a deeply nested structure
to an error-handling routine, raise an exception rather than use a GOTO statement.

By Subhash Reddy Aedla Page 216 of 304


ORACLE

PL/SQL's exception-handling mechanism is discussed in Chapter 10, " Handling PL/SQL


Errors".
Using the GOTO Statement
The GOTO statement branches to a label unconditionally. The label must be unique
within its scope and must precede an executable statement or a PL/SQL block. When
executed, the GOTO statement transfers control to the labeled statement or block. In the
following example, you go to an executable statement farther down in a sequence of
statements:
BEGIN
...
GOTO insert_row;
...
<<insert_row>>
INSERT INTO emp VALUES ...
END;

In the next example, you go to a PL/SQL block farther up in a sequence of statements:


DECLARE
x NUMBER := 0;
BEGIN
<<increment_x>>
BEGIN
x := x + 1;
END;
IF x < 10 THEN
GOTO increment_x;
END IF;
END;

The label end_loop in the following example is not allowed because it does not precede
an executable statement:
DECLARE
done BOOLEAN;
BEGIN
FOR i IN 1..50 LOOP
IF done THEN

By Subhash Reddy Aedla Page 217 of 304


ORACLE

GOTO end_loop;
END IF;
<<end_loop>> -- not allowed
END LOOP; -- not an executable statement
END;

To correct the previous example, add the NULL statement::


FOR i IN 1..50 LOOP
IF done THEN
GOTO end_loop;
END IF;
...
<<end_loop>>
NULL; -- an executable statement
END LOOP;

As the following example shows, a GOTO statement can branch to an enclosing block
from the current block:
DECLARE
my_ename CHAR(10);
BEGIN
<<get_name>>
SELECT ename INTO my_ename FROM emp WHERE ...
BEGIN
GOTO get_name; -- branch to enclosing block
END;
END;

The GOTO statement branches to the first enclosing block in which the referenced label
appears.

Restrictions on the GOTO Statement


Some possible destinations of a GOTO statement are not allowed. Specifically, a GOTO
statement cannot branch into an IF statement, CASE statement, LOOP statement, or sub-
block. For example, the following GOTO statement is not allowed:
BEGIN

By Subhash Reddy Aedla Page 218 of 304


ORACLE

GOTO update_row; -- can't branch into IF statement


IF valid THEN
<<update_row>>
UPDATE emp SET ...
END IF;
END;

A GOTO statement cannot branch from one IF statement clause to another, or from one
CASE statement WHEN clause to another.

A GOTO statement cannot branch from an outer block into a sub-block (that is, an inner
BEGIN-END block).

A GOTO statement cannot branch out of a subprogram. To end a subprogram early, you
can use the RETURN statement or use GOTO to branch to a place right before the end of
the subprogram.
A GOTO statement cannot branch from an exception handler back into the current BEGIN-
END block. However, a GOTO statement can branch from an exception handler into an
enclosing block.

Using Cursor Attributes


Every explicit cursor and cursor variable has four attributes: %FOUND, %ISOPEN
%NOTFOUND, and %ROWCOUNT. When appended to the cursor or cursor variable, these
attributes return useful information about the execution of a data manipulation
statement. You can use cursor attributes in procedural statements but not in SQL
statements.
Overview of Explicit Cursor Attributes
Explicit cursor attributes return information about the execution of a multi-row query.
When an explicit cursor or a cursor variable is opened, the rows that satisfy the
associated query are identified and form the result set. Rows are fetched from the result
set.

%FOUND Attribute: Has a Row Been Fetched?


After a cursor or cursor variable is opened but before the first fetch, %FOUND returns
NULL. After any fetches, it returns TRUE if the last fetch returned a row, or FALSE if the last
fetch did not return a row. The following example uses %FOUND to select an action:
DECLARE
CURSOR c1 IS SELECT last_name, salary FROM employees WHERE ROWNUM < 11;

By Subhash Reddy Aedla Page 219 of 304


ORACLE

my_ename employees.last_name%TYPE;
my_salary employees.salary%TYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO my_ename, my_salary;
IF c1%FOUND THEN -- fetch succeeded
dbms_output.put_line('Name = ' || my_ename || ', salary = ' ||
my_salary);
ELSE -- fetch failed, so exit loop
EXIT;
END IF;
END LOOP;
END;
/
If a cursor or cursor variable is not open, referencing it with %FOUND raises the
predefined exception INVALID_CURSOR.

%ISOPEN Attribute: Is the Cursor Open?


%ISOPEN returns TRUE if its cursor or cursor variable is open; otherwise, %ISOPEN returns
FALSE. The following example uses %ISOPEN to select an action:
DECLARE
CURSOR c1 IS SELECT last_name, salary FROM employees WHERE ROWNUM < 11;
the_name employees.last_name%TYPE;
the_salary employees.salary%TYPE;
BEGIN
IF c1%ISOPEN = FALSE THEN -- cursor was not already open
OPEN c1;
END IF;
FETCH c1 INTO the_name, the_salary;
CLOSE c1;
END;
/

%NOTFOUND Attribute: Has a Fetch Failed?


%NOTFOUND is the logical opposite of %FOUND. %NOTFOUND yields FALSE if the last fetch
returned a row, or TRUE if the last fetch failed to return a row. In the following example,
you use %NOTFOUND to exit a loop when FETCH fails to return a row:

By Subhash Reddy Aedla Page 220 of 304


ORACLE

DECLARE
CURSOR c1 IS SELECT last_name, salary FROM employees WHERE ROWNUM < 11;
my_ename employees.last_name%TYPE;
my_salary employees.salary%TYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO my_ename, my_salary;
IF c1%NOTFOUND THEN -- fetch failed, so exit loop
-- A shorter form of this test is "EXIT WHEN c1%NOTFOUND;"
EXIT;
ELSE -- fetch succeeded
dbms_output.put_line('Name = ' || my_ename || ', salary = ' ||
my_salary);
END IF;
END LOOP;
END;
/
Before the first fetch, %NOTFOUND returns NULL. If FETCH never executes successfully, the
loop is never exited, because the EXIT WHEN statement executes only if its WHEN
condition is true. To be safe, you might want to use the following EXIT statement instead:
EXIT WHEN c1%NOTFOUND OR c1%NOTFOUND IS NULL;
If a cursor or cursor variable is not open, referencing it with %NOTFOUND raises an
INVALID_CURSOR exception.

%ROWCOUNT Attribute: How Many Rows Fetched So Far?


When its cursor or cursor variable is opened, %ROWCOUNT is zeroed. Before the first
fetch, %ROWCOUNT yields 0. Thereafter, it yields the number of rows fetched so far. The
number is incremented if the last fetch returned a row. The following example uses
%ROWCOUNT to test if more than ten rows have been fetched:
DECLARE
CURSOR c1 IS SELECT last_name FROM employees WHERE ROWNUM < 11;
name employees.last_name%TYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO name;

By Subhash Reddy Aedla Page 221 of 304


ORACLE

EXIT WHEN c1%NOTFOUND;


dbms_output.put_line(c1%ROWCOUNT || '. ' || name);
IF c1%ROWCOUNT = 5 THEN
dbms_output.put_line('--- Fetched 5th record ---');
END IF;
END LOOP;
CLOSE c1;
END;
/
If a cursor or cursor variable is not open, referencing it with %ROWCOUNT raises
INVALID_CURSOR.

Table - shows what each cursor attribute returns before and after you execute an OPEN,
FETCH, or CLOSE statement.

Table - Cursor Attribute Values

%FOUND %ISOPEN %NOTFOUND %ROWCOUNT

OPEN before exception FALSE exception exception

after NULL TRUE NULL 0

First FETCH before NULL TRUE NULL 0

after TRUE TRUE FALSE 1

Next before TRUE TRUE FALSE 1


FETCH(es)

after TRUE TRUE FALSE data dependent

Last FETCH before TRUE TRUE FALSE data dependent

after FALSE TRUE TRUE data dependent

CLOSE before FALSE TRUE TRUE data dependent

after exception FALSE exception exception

Notes:
1. Referencing %FOUND, %NOTFOUND, or %ROWCOUNT before a cursor is opened or

By Subhash Reddy Aedla Page 222 of 304


ORACLE

%FOUND %ISOPEN %NOTFOUND %ROWCOUNT


after it is closed raises INVALID_CURSOR.
2. After the first FETCH, if the result set was empty, %FOUND yields FALSE, %NOTFOUND
yields TRUE, and %ROWCOUNT yields 0.

Using Cursor Variables (REF CURSORs)


Like a cursor, a cursor variable points to the current row in the result set of a multi-row
query. A cursor variable is more flexible because it is not tied to a specific query. You
can open a cursor variable for any query that returns the right set of columns.
You pass a cursor variable as a parameter to local and stored subprograms. Opening the
cursor variable in one subprogram, and processing it in a different subprogram, helps to
centralize data retrieval. This technique is also useful for multi-language applications,
where a PL/SQL subprogram might return a result set to a subprogram written in a
different language.
Cursor variables are available to every PL/SQL client. For example, you can declare a
cursor variable in a PL/SQL host environment such as an OCI or Pro*C program, then
pass it as an input host variable (bind variable) to PL/SQL. Application development tools
such as Oracle Forms and Oracle Reports, which have a PL/SQL engine, can use cursor
variables entirely on the client side. Or, you can pass cursor variables back and forth
between a client and the database server through remote procedure calls.
What Are Cursor Variables (REF CURSORs)?
Cursor variables are like pointers to result sets. You use them when you want to
perform a query in one subprogram, and process the results in a different subprogram
(possibly one written in a different language). A cursor variable has datatype REF CURSOR,
and you might see them referred to informally as REF CURSORs.
Unlike an explicit cursor, which always refers to the same query work area, a cursor
variable can refer to different work areas. You cannot use a cursor variable where a
cursor is expected, or vice versa.
Why Use Cursor Variables?
You use cursor variables to pass query result sets between PL/SQL stored subprograms
and various clients. PL/SQL and its clients share a pointer to the query work area in
which the result set is stored. For example, an OCI client, Oracle Forms application, and
Oracle database server can all refer to the same work area.

By Subhash Reddy Aedla Page 223 of 304


ORACLE

A query work area remains accessible as long as any cursor variable points to it, as you
pass the value of a cursor variable from one scope to another. For example, if you pass a
host cursor variable to a PL/SQL block embedded in a Pro*C program, the work area to
which the cursor variable points remains accessible after the block completes.
If you have a PL/SQL engine on the client side, calls from client to server impose no
restrictions. For example, you can declare a cursor variable on the client side, open and
fetch from it on the server side, then continue to fetch from it back on the client side.
You can also reduce network traffic by having a PL/SQL block open or close several host
cursor variables in a single round trip.
Declaring REF CURSOR Types and Cursor Variables
To create cursor variables, you define a REF CURSOR type, then declare cursor variables of
that type. You can define REF CURSOR types in any PL/SQL block, subprogram, or package.
In the following example, you declare a REF CURSOR type that represents a result set from
the DEPARTMENTS table:
DECLARE
TYPE DeptCurTyp IS REF CURSOR RETURN departments%ROWTYPE;

REF CURSOR types can be strong (with a return type) or weak (with no return type).

Strong REF CURSOR types are less error prone because the PL/SQL compiler lets you
associate a strongly typed cursor variable only with queries that return the right set of
columns. Weak REF CURSOR types are more flexible because the compiler lets you
associate a weakly typed cursor variable with any query.
Because there is no type checking with a weak REF CURSOR, all such types are
interchangeable. Instead of creating a new type, you can use the predefined type
SYS_REFCURSOR.

Once you define a REF CURSOR type, you can declare cursor variables of that type in any
PL/SQL block or subprogram.
DECLARE
TYPE EmpCurTyp IS REF CURSOR RETURN emp%ROWTYPE; -- strong
TYPE GenericCurTyp IS REF CURSOR; -- weak
cursor1 EmpCurTyp;
cursor2 GenericCurTyp;
my_cursor SYS_REFCURSOR; -- didn't need to declare a new type above

By Subhash Reddy Aedla Page 224 of 304


ORACLE

The following example declares the cursor variable dept_cv:


DECLARE
TYPE DeptCurTyp IS REF CURSOR RETURN dept%ROWTYPE;
dept_cv DeptCurTyp; -- declare cursor variable

To avoid declaring the same REF CURSOR type in each subprogram that uses it, you can
put the REF CURSOR declaration in a package spec. You can declare cursor variables of
that type in the corresponding package body, or within your own procedure or function.
Example - Cursor Variable Returning %ROWTYPE
In the RETURN clause of a REF CURSOR type definition, you can use %ROWTYPE to refer to a
strongly typed cursor variable:
DECLARE
TYPE TmpCurTyp IS REF CURSOR RETURN employees%ROWTYPE;
tmp_cv TmpCurTyp; -- declare cursor variable
TYPE EmpCurTyp IS REF CURSOR RETURN tmp_cv%ROWTYPE;
emp_cv EmpCurTyp; -- declare cursor variable
BEGIN
NULL;
END;
/
Example - Cursor Variable Returning %TYPE
You can also use %TYPE to provide the datatype of a record variable:
DECLARE
dept_rec departments%ROWTYPE; -- declare record variable
TYPE DeptCurTyp IS REF CURSOR RETURN dept_rec%TYPE;
dept_cv DeptCurTyp; -- declare cursor variable
BEGIN
NULL;
END;
/
Example - Cursor Variable Returning Record Type
This example specifies a user-defined RECORD type in the RETURN clause:
DECLARE
TYPE EmpRecTyp IS RECORD (
employee_id NUMBER,

By Subhash Reddy Aedla Page 225 of 304


ORACLE

last_name VARCHAR2(30),
salary NUMBER(7,2));
TYPE EmpCurTyp IS REF CURSOR RETURN EmpRecTyp;
emp_cv EmpCurTyp; -- declare cursor variable
BEGIN
NULL;
END;
/

Passing Cursor Variables As Parameters


You can declare cursor variables as the formal parameters of functions and procedures.
The following example defines a REF CURSOR type, then declares a cursor variable of that
type as a formal parameter:
DECLARE
TYPE EmpCurTyp IS REF CURSOR RETURN employees%ROWTYPE;
emp EmpCurTyp;

-- Once we have a result set, we can process all the rows


-- inside a single procedure rather than calling a procedure
-- for each row.
PROCEDURE process_emp_cv (emp_cv IN EmpCurTyp) IS
person employees%ROWTYPE;
BEGIN
dbms_output.put_line('-----');
dbms_output.put_line('Here are the names from the result set:');
LOOP
FETCH emp_cv INTO person;
EXIT WHEN emp_cv%NOTFOUND;
dbms_output.put_line('Name = ' || person.first_name ||
' ' || person.last_name);
END LOOP;
END;

BEGIN
-- First find 10 arbitrary employees.
OPEN emp FOR SELECT * FROM employees WHERE ROWNUM < 11;

By Subhash Reddy Aedla Page 226 of 304


ORACLE

process_emp_cv(emp);
CLOSE emp;
-- Then find employees matching a condition.
OPEN emp FOR SELECT * FROM employees WHERE last_name LIKE 'R%';
process_emp_cv(emp);
CLOSE emp;
END;
/
Note: Like all pointers, cursor variables increase the possibility of parameter aliasing.
Controlling Cursor Variables: OPEN-FOR, FETCH, and CLOSE
You use three statements to control a cursor variable: OPEN-FOR, FETCH, and CLOSE. First,
you OPEN a cursor variable FOR a multi-row query. Then, you FETCH rows from the result
set. When all the rows are processed, you CLOSE the cursor variable.

Opening a Cursor Variable


The OPEN-FOR statement associates a cursor variable with a multi-row query, executes
the query, and identifies the result set.
OPEN {cursor_variable | :host_cursor_variable} FOR
{ select_statement
| dynamic_string [USING bind_argument[, bind_argument]...] };

The cursor variable can be declared directly in PL/SQL, or in a PL/SQL host environment
such as an OCI program.
The SELECT statement for the query can be coded directly in the statement, or can be a
string variable or string literal. When you use a string as the query, it can include
placeholders for bind variables, and you specify the corresponding values with a USING
clause.
Note: This section discusses the static SQL case, in which select_statement is used. For the
dynamic SQL case, in which dynamic_string is used.
Unlike cursors, cursor variables take no parameters. Instead, you can pass whole queries
(not just parameters) to a cursor variable. The query can reference host variables and
PL/SQL variables, parameters, and functions.
The example below opens a cursor variable. Notice that you can apply cursor attributes
(%FOUND, %NOTFOUND, %ISOPEN, and %ROWCOUNT) to a cursor variable.

By Subhash Reddy Aedla Page 227 of 304


ORACLE

DECLARE
TYPE EmpCurTyp IS REF CURSOR RETURN employees%ROWTYPE;
emp_cv EmpCurTyp;
BEGIN
IF NOT emp_cv%ISOPEN THEN
/* Open cursor variable. */
OPEN emp_cv FOR SELECT * FROM employees;
END IF;
CLOSE emp_cv;
END;
/
Other OPEN-FOR statements can open the same cursor variable for different queries. You
need not close a cursor variable before reopening it. (Recall that consecutive OPENs of a
static cursor raise the predefined exception CURSOR_ALREADY_OPEN.) When you reopen a
cursor variable for a different query, the previous query is lost.
Example - Stored Procedure to Open a Ref Cursor
Typically, you open a cursor variable by passing it to a stored procedure that declares an
IN OUT parameter that is a cursor variable. For example, the following procedure opens
a cursor variable:
CREATE PACKAGE emp_data AS
TYPE EmpCurTyp IS REF CURSOR RETURN employees%ROWTYPE;
PROCEDURE open_emp_cv (emp_cv IN OUT EmpCurTyp);
END emp_data;
/

CREATE PACKAGE BODY emp_data AS


PROCEDURE open_emp_cv (emp_cv IN OUT EmpCurTyp) IS
BEGIN
OPEN emp_cv FOR SELECT * FROM employees;
END open_emp_cv;
END emp_data;
/

DROP PACKAGE emp_data;

By Subhash Reddy Aedla Page 228 of 304


ORACLE

You can also use a standalone stored procedure to open the cursor variable. Define the
REF CURSOR type in a package, then reference that type in the parameter declaration for
the stored procedure.
Example - Stored Procedure to Open Ref Cursors with Different Queries
To centralize data retrieval, you can group type-compatible queries in a stored
procedure. In the example below, the packaged procedure declares a selector as one of
its formal parameters. When called, the procedure opens the cursor variable emp_cv for
the chosen query.
CREATE PACKAGE emp_data AS
TYPE EmpCurTyp IS REF CURSOR RETURN emp%ROWTYPE;
PROCEDURE open_emp_cv (emp_cv IN OUT EmpCurTyp, choice INT);
END emp_data;

CREATE PACKAGE BODY emp_data AS


PROCEDURE open_emp_cv (emp_cv IN OUT EmpCurTyp, choice INT) IS
BEGIN
IF choice = 1 THEN
OPEN emp_cv FOR SELECT * FROM emp WHERE comm IS NOT NULL;
ELSIF choice = 2 THEN
OPEN emp_cv FOR SELECT * FROM emp WHERE sal > 2500;
ELSIF choice = 3 THEN
OPEN emp_cv FOR SELECT * FROM emp WHERE deptno = 20;
END IF;
END;
END emp_data;

Example - Cursor Variable with Different Return Types


For more flexibility, a stored procedure can execute queries with different return types:
CREATE PACKAGE admin_data AS
TYPE GenCurTyp IS REF CURSOR;
PROCEDURE open_cv (generic_cv IN OUT GenCurTyp, choice INT);
END admin_data;

CREATE PACKAGE BODY admin_data AS


PROCEDURE open_cv (generic_cv IN OUT GenCurTyp, choice INT) IS
BEGIN

By Subhash Reddy Aedla Page 229 of 304


ORACLE

IF choice = 1 THEN
OPEN generic_cv FOR SELECT * FROM emp;
ELSIF choice = 2 THEN
OPEN generic_cv FOR SELECT * FROM dept;
ELSIF choice = 3 THEN
OPEN generic_cv FOR SELECT * FROM salgrade;
END IF;
END;
END admin_data;

Using a Cursor Variable as a Host Variable


You can declare a cursor variable in a PL/SQL host environment such as an OCI or Pro*C
program. To use the cursor variable, you must pass it as a host variable to PL/SQL. In the
following Pro*C example, you pass a host cursor variable and selector to a PL/SQL block,
which opens the cursor variable for the chosen query:
EXEC SQL BEGIN DECLARE SECTION;
...
/* Declare host cursor variable. */
SQL_CURSOR generic_cv;
int choice;
EXEC SQL END DECLARE SECTION;
...
/* Initialize host cursor variable. */
EXEC SQL ALLOCATE :generic_cv;
...
/* Pass host cursor variable and selector to PL/SQL block. */
EXEC SQL EXECUTE
BEGIN
IF :choice = 1 THEN
OPEN :generic_cv FOR SELECT * FROM emp;
ELSIF :choice = 2 THEN
OPEN :generic_cv FOR SELECT * FROM dept;
ELSIF :choice = 3 THEN
OPEN :generic_cv FOR SELECT * FROM salgrade;
END IF;
END;
END-EXEC;

By Subhash Reddy Aedla Page 230 of 304


ORACLE

Host cursor variables are compatible with any query return type. They behave just like
weakly typed PL/SQL cursor variables.

Fetching from a Cursor Variable


The FETCH statement retrieves rows from the result set of a multi-row query. It works
the same with cursor variables as with explicit cursors.
Example - Fetching from a Cursor Variable into a Record
The following example fetches rows one at a time from a cursor variable into a record:
DECLARE
TYPE EmpCurTyp IS REF CURSOR RETURN employees%ROWTYPE;
emp_cv EmpCurTyp;
emp_rec employees%ROWTYPE;
BEGIN
OPEN emp_cv FOR SELECT * FROM employees WHERE salary < 3000;
LOOP
/* Fetch from cursor variable. */
FETCH emp_cv INTO emp_rec;
EXIT WHEN emp_cv%NOTFOUND; -- exit when last row is fetched
-- process data record
dbms_output.put_line('Name = ' || emp_rec.first_name || ' ' ||
emp_rec.last_name);
END LOOP;
CLOSE emp_cv;
END;
/
Example - Fetching from a Cursor Variable into Collections
Using the BULK COLLECT clause, you can bulk fetch rows from a cursor variable into one or
more collections:
DECLARE
TYPE EmpCurTyp IS REF CURSOR;
TYPE NameList IS TABLE OF employees.last_name%TYPE;
TYPE SalList IS TABLE OF employees.salary%TYPE;
emp_cv EmpCurTyp;
names NameList;
sals SalList;
BEGIN
OPEN emp_cv FOR SELECT last_name, salary FROM employees WHERE salary < 3000;

By Subhash Reddy Aedla Page 231 of 304


ORACLE

FETCH emp_cv BULK COLLECT INTO names, sals;


CLOSE emp_cv;
-- Now loop through the NAMES and SALS collections.
FOR i IN names.FIRST .. names.LAST
LOOP
dbms_output.put_line('Name = ' || names(i) || ', salary = ' ||
sals(i));
END LOOP;
END;
/
Any variables in the associated query are evaluated only when the cursor variable is
opened. To change the result set or the values of variables in the query, reopen the
cursor variable with the variables set to new values. You can use a different INTO clause
on separate fetches with the same cursor variable. Each fetch retrieves another row
from the same result set.
PL/SQL makes sure the return type of the cursor variable is compatible with the INTO
clause of the FETCH statement. If there is a mismatch, an error occurs at compile time if
the cursor variable is strongly typed, or at run time if it is weakly typed. At run time,
PL/SQL raises the predefined exception ROWTYPE_MISMATCH before the first fetch. If you
trap the error and execute the FETCH statement using a different (compatible) INTO
clause, no rows are lost.
When you declare a cursor variable as the formal parameter of a subprogram that
fetches from the cursor variable, you must specify the IN or IN OUT mode. If the
subprogram also opens the cursor variable, you must specify the IN OUT mode.
If you try to fetch from a closed or never-opened cursor variable, PL/SQL raises the
predefined exception INVALID_CURSOR.

Closing a Cursor Variable


The CLOSE statement disables a cursor variable and makes the associated result set
undefined. Close the cursor variable after the last row is processed.
When declaring a cursor variable as the formal parameter of a subprogram that closes
the cursor variable, you must specify the IN or IN OUT mode.
If you try to close an already-closed or never-opened cursor variable, PL/SQL raises the
predefined exception INVALID_CURSOR.

By Subhash Reddy Aedla Page 232 of 304


ORACLE

Reducing Network Traffic When Passing Host Cursor Variables to PL/SQL


When passing host cursor variables to PL/SQL, you can reduce network traffic by
grouping OPEN-FOR statements. For example, the following PL/SQL block opens multiple
cursor variables in a single round trip:
/* anonymous PL/SQL block in host environment */
BEGIN
OPEN :emp_cv FOR SELECT * FROM employees;
OPEN :dept_cv FOR SELECT * FROM departments;
OPEN :loc_cv FOR SELECT * FROM locations;
END;

This technique might be useful in Oracle Forms, for instance, when you want to
populate a multi-block form.
When you pass host cursor variables to a PL/SQL block for opening, the query work
areas to which they point remain accessible after the block completes, so your OCI or
Pro*C program can use these work areas for ordinary cursor operations. In the following
example, you open several such work areas in a single round trip:
BEGIN
OPEN :c1 FOR SELECT 1 FROM dual;
OPEN :c2 FOR SELECT 1 FROM dual;
OPEN :c3 FOR SELECT 1 FROM dual;
END;

The cursors assigned to c1, c2, and c3 behave normally, and you can use them for any
purpose. When finished, release the cursors as follows:
BEGIN
CLOSE :c1;
CLOSE :c2;
CLOSE :c3;
END;

By Subhash Reddy Aedla Page 233 of 304


ORACLE

Avoiding Errors with Cursor Variables


If both cursor variables involved in an assignment are strongly typed, they must have
exactly the same datatype (not just the same return type). If one or both cursor
variables are weakly typed, they can have different datatypes.
If you try to fetch from, close, or refer to cursor attributes of a cursor variable that does
not point to a query work area, PL/SQL raises the INVALID_CURSOR exception. You can
make a cursor variable (or parameter) point to a query work area in two ways:
 OPEN the cursor variable FOR the query.

 Assign to the cursor variable the value of an already OPENed host cursor variable
or PL/SQL cursor variable.
If you assign an unopened cursor variable to another cursor variable, the second one
remains invalid even after you open the first one.
Be careful when passing cursor variables as parameters. At run time, PL/SQL raises
ROWTYPE_MISMATCH if the return types of the actual and formal parameters are
incompatible.
Restrictions on Cursor Variables
Currently, cursor variables are subject to the following restrictions:
 You cannot declare cursor variables in a package spec. For example, the
following declaration is not allowed:
 CREATE PACKAGE emp_stuff AS
 TYPE EmpCurTyp IS REF CURSOR RETURN emp%ROWTYPE;
 emp_cv EmpCurTyp; -- not allowed
 END emp_stuff;

 You cannot pass cursor variables to a procedure that is called through a database
link.
 If you pass a host cursor variable to PL/SQL, you cannot fetch from it on the
server side unless you also open it there on the same server call.
 You cannot use comparison operators to test cursor variables for equality,
inequality, or nullity.
 You cannot assign nulls to a cursor variable.

By Subhash Reddy Aedla Page 234 of 304


ORACLE

 Database columns cannot store the values of cursor variables. There is no


equivalent type to use in a CREATE TABLE statement.
 You cannot store cursor variables in an associative array, nested table, or varray.
 Cursors and cursor variables are not interoperable; that is, you cannot use one
where the other is expected. For example, you cannot reference a cursor
variable in a cursor FOR loop.
Using Cursor Expressions
A cursor expression returns a nested cursor. Each row in the result set can contain
values as usual, plus cursors produced by subqueries involving the other values in the
row. A single query can return a large set of related values retrieved from multiple
tables. You can process the result set with nested loops that fetch first from the rows of
the result set, then from any nested cursors within those rows.
PL/SQL supports queries with cursor expressions as part of cursor declarations, REF
CURSOR declarations and ref cursor variables. You can also use cursor expressions in
dynamic SQL queries. Here is the syntax:
CURSOR(subquery)

A nested cursor is implicitly opened when the containing row is fetched from the parent
cursor. The nested cursor is closed only when:
 The nested cursor is explicitly closed by the user
 The parent cursor is reexecuted
 The parent cursor is closed
 The parent cursor is canceled
 An error arises during a fetch on one of its parent cursors. The nested cursor is
closed as part of the clean-up.
Restrictions on Cursor Expressions
 You cannot use a cursor expression with an implicit cursor.
 Cursor expressions can appear only:
 In a SELECT statement that is not nested in any other query expression,
except when it is a subquery of the cursor expression itself.
 As arguments to table functions, in the FROM clause of a SELECT statement.

By Subhash Reddy Aedla Page 235 of 304


ORACLE

 Cursor expressions can appear only in the outermost SELECT list of the query
specification.
 Cursor expressions cannot appear in view declarations.
 You cannot perform BIND and EXECUTE operations on cursor expressions.
Example of Cursor Expressions
In this example, we find a specified location ID, and a cursor from which we can fetch all
the departments in that location. As we fetch each department's name, we also get
another cursor that lets us fetch their associated employee details from another table.
DECLARE
TYPE emp_cur_typ IS REF CURSOR;
emp_cur emp_cur_typ;
dept_name departments.department_name%TYPE;
emp_name employees.last_name%TYPE;
CURSOR c1 IS SELECT
department_name,
-- The 2nd item in the result set is another result set,
-- which is represented as a ref cursor and labelled "employees".
CURSOR
(
SELECT e.last_name FROM employees e
WHERE e.department_id = d.department_id
) employees
FROM departments d
WHERE department_name like 'A%';

BEGIN
OPEN c1;
LOOP
FETCH c1 INTO dept_name, emp_cur;
EXIT WHEN c1%NOTFOUND;
dbms_output.put_line('Department: ' || dept_name);
-- For each row in the result set, we can process the result
-- set from a subquery. We could pass the ref cursor to a procedure
-- instead of processing it here in the loop.
LOOP
FETCH emp_cur INTO emp_name;

By Subhash Reddy Aedla Page 236 of 304


ORACLE

EXIT WHEN emp_cur%NOTFOUND;


dbms_output.put_line(' Employee: ' || emp_name);
END LOOP;
END LOOP;
CLOSE c1;
END;
/
Constructing REF CURSORs with Cursor Subqueries
You can use cursor subqueries, also know as cursor expressions, to pass sets of rows as
parameters to functions. For example, this statement passes a parameter to the
StockPivot function consisting of a REF CURSOR that represents the rows returned by the
cursor subquery:
SELECT * FROM TABLE(StockPivot(CURSOR(SELECT * FROM StockTable)));

Overview of Transaction Processing in PL/SQL


This section explains how to do transaction processing with PL/SQL.
You should already be familiar with the idea of transactions, and how to ensure the
consistency of a database, such as the COMMIT, SAVEPOINT, and ROLLBACK statements.
These are Oracle features, available through all programming languages, that let
multiple users work on the database concurrently, and ensure that each user sees a
consistent version of data and that all changes are applied in the right order.
You usually do not need to write extra code to prevent problems with multiple users
accessing data concurrently. Oracle uses locks to control concurrent access to data, and
locks only the minimum amount of data necessary, for as little time as possible. You can
request locks on tables or rows if you really do need this level of control. You can choose
from several modes of locking such as row share and exclusive.
Using COMMIT, SAVEPOINT, and ROLLBACK in PL/SQL
You can include COMMIT, SAVEPOINT, and ROLLBACK statements directly in your PL/SQL
programs.
The COMMIT statement ends the current transaction, making any changes made during
that transaction permanent, and visible to other users.
The ROLLBACK statement ends the current transaction and undoes any changes made
during that transaction. If you make a mistake, such as deleting the wrong row from a
table, a rollback restores the original data. If you cannot finish a transaction because an

By Subhash Reddy Aedla Page 237 of 304


ORACLE

exception is raised or a SQL statement fails, a rollback lets you take corrective action
and perhaps start over.
SAVEPOINT names and marks the current point in the processing of a transaction.
Savepoints let you roll back part of a transaction instead of the whole transaction.
Consider a transaction that transfers money from one bank account to another. It is
important that the money come out of one account, and into the other, at exactly the
same moment. Otherwise, a problem partway through might make the money be lost
from both accounts or be duplicated in both accounts.
BEGIN
UPDATE accts SET bal = my_bal - debit
WHERE acctno = 7715;
UPDATE accts SET bal = my_bal + credit
WHERE acctno = 7720;
COMMIT WORK;
END;

Transactions are not tied to PL/SQL BEGIN-END blocks. A block can contain multiple
transactions, and a transaction can span multiple blocks.
The optional COMMENT clause lets you specify a comment to be associated with a
distributed transaction. If a network or machine fails during the commit, the state of the
distributed transaction might be unknown or in doubt. In that case, Oracle stores the
text specified by COMMENT in the data dictionary along with the transaction ID. The text
must be a quoted literal up to 50 characters long:
COMMIT COMMENT 'In-doubt order transaction; notify Order Entry';

PL/SQL does not support the FORCE clause of SQL, which manually commits an in-doubt
distributed transaction.
The following example inserts information about an employee into three different
database tables. If an INSERT statement tries to store a duplicate employee number, the
predefined exception DUP_VAL_ON_INDEX is raised. To make sure that changes to all three
tables are undone, the exception handler executes a ROLLBACK.
DECLARE
emp_id INTEGER;
BEGIN
SELECT empno, ... INTO emp_id, ... FROM new_emp WHERE ...

By Subhash Reddy Aedla Page 238 of 304


ORACLE

INSERT INTO emp VALUES (emp_id, ...);


INSERT INTO tax VALUES (emp_id, ...);
INSERT INTO pay VALUES (emp_id, ...);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
ROLLBACK;
END;

Statement-Level Rollbacks
Before executing a SQL statement, Oracle marks an implicit savepoint. Then, if the
statement fails, Oracle rolls it back automatically. For example, if an INSERT statement
raises an exception by trying to insert a duplicate value in a unique index, the statement
is rolled back. Only work started by the failed SQL statement is lost. Work done before
that statement in the current transaction is kept.
Oracle can also roll back single SQL statements to break deadlocks. Oracle signals an
error to one of the participating transactions and rolls back the current statement in
that transaction.
Before executing a SQL statement, Oracle must parse it, that is, examine it to make sure
it follows syntax rules and refers to valid schema objects. Errors detected while
executing a SQL statement cause a rollback, but errors detected while parsing the
statement do not.
The following example marks a savepoint before doing an insert. If the INSERT statement
tries to store a duplicate value in the empno column, the predefined exception
DUP_VAL_ON_INDEX is raised. In that case, you roll back to the savepoint, undoing just the
insert.
DECLARE
emp_id emp.empno%TYPE;
BEGIN
UPDATE emp SET ... WHERE empno = emp_id;
DELETE FROM emp WHERE ...
SAVEPOINT do_insert;
INSERT INTO emp VALUES (emp_id, ...);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
ROLLBACK TO do_insert;
END;

By Subhash Reddy Aedla Page 239 of 304


ORACLE

When you roll back to a savepoint, any savepoints marked after that savepoint are
erased. The savepoint to which you roll back is not erased. A simple rollback or commit
erases all savepoints.
If you mark a savepoint within a recursive subprogram, new instances of the SAVEPOINT
statement are executed at each level in the recursive descent, but you can only roll back
to the most recently marked savepoint.
Savepoint names are undeclared identifiers. Reusing a savepoint name within a
transaction moves the savepoint from its old position to the current point in the
transaction. Thus, a rollback to the savepoint affects only the current part of your
transaction:
BEGIN
SAVEPOINT my_point;
UPDATE emp SET ... WHERE empno = emp_id;
SAVEPOINT my_point; -- move my_point to current point
INSERT INTO emp VALUES (emp_id, ...);
EXCEPTION
WHEN OTHERS THEN
ROLLBACK TO my_point;
END;

The number of active savepoints for each session is unlimited.


How Oracle Does Implicit Rollbacks
Before executing an INSERT, UPDATE, or DELETE statement, Oracle marks an implicit
savepoint (unavailable to you). If the statement fails, Oracle rolls back to the savepoint.
Normally, just the failed SQL statement is rolled back, not the whole transaction. If the
statement raises an unhandled exception, the host environment determines what is
rolled back.
If you exit a stored subprogram with an unhandled exception, PL/SQL does not assign
values to OUT parameters, and does not do any rollback.
Ending Transactions
You should explicitly commit or roll back every transaction. Whether you issue the
commit or rollback in your PL/SQL program or from a client program depends on the
application logic. If you do not commit or roll back a transaction explicitly, the client
environment determines its final state.

By Subhash Reddy Aedla Page 240 of 304


ORACLE

For example, in the SQL*Plus environment, if your PL/SQL block does not include a
COMMIT or ROLLBACK statement, the final state of your transaction depends on what you
do after running the block. If you execute a data definition, data control, or COMMIT
statement or if you issue the EXIT, DISCONNECT, or QUIT command, Oracle commits the
transaction. If you execute a ROLLBACK statement or abort the SQL*Plus session, Oracle
rolls back the transaction.
Oracle precompiler programs roll back the transaction unless the program explicitly
commits or rolls back work, and disconnects using the RELEASE parameter:
EXEC SQL COMMIT WORK RELEASE;
Setting Transaction Properties with SET TRANSACTION
You use the SET TRANSACTION statement to begin a read-only or read-write transaction,
establish an isolation level, or assign your current transaction to a specified rollback
segment. Read-only transactions are useful for running multiple queries while other
users update the same tables.
During a read-only transaction, all queries refer to the same snapshot of the database,
providing a multi-table, multi-query, read-consistent view. Other users can continue to
query or update data as usual. A commit or rollback ends the transaction. In the
example below a store manager uses a read-only transaction to gather sales figures for
the day, the past week, and the past month. The figures are unaffected by other users
updating the database during the transaction.
DECLARE
daily_sales REAL;
weekly_sales REAL;
monthly_sales REAL;
BEGIN
COMMIT; -- ends previous transaction
SET TRANSACTION READ ONLY NAME 'Calculate sales figures';
SELECT SUM(amt) INTO daily_sales FROM sales
WHERE dte = SYSDATE;
SELECT SUM(amt) INTO weekly_sales FROM sales
WHERE dte > SYSDATE - 7;
SELECT SUM(amt) INTO monthly_sales FROM sales
WHERE dte > SYSDATE - 30;
COMMIT; -- ends read-only transaction
END;

By Subhash Reddy Aedla Page 241 of 304


ORACLE

The SET TRANSACTION statement must be the first SQL statement in a read-only
transaction and can only appear once in a transaction. If you set a transaction to READ
ONLY, subsequent queries see only changes committed before the transaction began.
The use of READ ONLY does not affect other users or transactions.

Restrictions on SET TRANSACTION


Only the SELECT INTO, OPEN, FETCH, CLOSE, LOCK TABLE, COMMIT, and ROLLBACK statements are
allowed in a read-only transaction. Queries cannot be FOR UPDATE.
Overriding Default Locking
By default, Oracle locks data structures for you automatically, which is a major strength
of the Oracle database: different applications can read and write to the same data
without harming each other's data or coordinating with each other.
You can request data locks on specific rows or entire tables if you need to override
default locking. Explicit locking lets you deny access to data for the duration of a
transaction.:
 With the LOCK TABLE statement, you can explicitly lock entire tables.
 With the SELECT FOR UPDATE statement, you can explicitly lock specific rows of a
table to make sure they do not change after you have read them. That way, you
can check which or how many rows will be affected by an UPDATE or DELETE
statement before issuing the statement, and no other application can change the
rows in the meantime.

Using FOR UPDATE


When you declare a cursor that will be referenced in the CURRENT OF clause of an UPDATE
or DELETE statement, you must use the FOR UPDATE clause to acquire exclusive row locks.
An example follows:
DECLARE
CURSOR c1 IS SELECT empno, sal FROM emp
WHERE job = 'SALESMAN' AND comm > sal
FOR UPDATE NOWAIT;

The SELECT ... FOR UPDATE statement identifies the rows that will be updated or deleted,
then locks each row in the result set. This is useful when you want to base an update on
the existing values in a row. In that case, you must make sure the row is not changed by
another user before the update.

By Subhash Reddy Aedla Page 242 of 304


ORACLE

The optional keyword NOWAIT tells Oracle not to wait if requested rows have been
locked by another user. Control is immediately returned to your program so that it can
do other work before trying again to acquire the lock. If you omit the keyword NOWAIT,
Oracle waits until the rows are available.
All rows are locked when you open the cursor, not as they are fetched. The rows are
unlocked when you commit or roll back the transaction. Since the rows are no longer
locked, you cannot fetch from a FOR UPDATE cursor after a commit. (For a workaround,
see "Fetching Across Commits".)
When querying multiple tables, you can use the FOR UPDATE clause to confine row
locking to particular tables. Rows in a table are locked only if the FOR UPDATE OF clause
refers to a column in that table. For example, the following query locks rows in the emp
table but not in the dept table:
DECLARE
CURSOR c1 IS SELECT ename, dname FROM emp, dept
WHERE emp.deptno = dept.deptno AND job = 'MANAGER'
FOR UPDATE OF sal;

As the next example shows, you use the CURRENT OF clause in an UPDATE or DELETE
statement to refer to the latest row fetched from a cursor:
DECLARE
CURSOR c1 IS SELECT empno, job, sal FROM emp FOR UPDATE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO ...
UPDATE emp SET sal = new_sal WHERE CURRENT OF c1;
END LOOP;

Using LOCK TABLE


You use the LOCK TABLE statement to lock entire database tables in a specified lock mode
so that you can share or deny access to them.. Row share locks allow concurrent access
to a table; they prevent other users from locking the entire table for exclusive use. Table
locks are released when your transaction issues a commit or rollback.
LOCK TABLE emp IN ROW SHARE MODE NOWAIT;

By Subhash Reddy Aedla Page 243 of 304


ORACLE

The lock mode determines what other locks can be placed on the table. For example,
many users can acquire row share locks on a table at the same time, but only one user
at a time can acquire an exclusive lock. While one user has an exclusive lock on a table,
no other users can insert, delete, or update rows in that table. For more information
about lock modes, see Oracle Database Application Developer's Guide -
Fundamentals.
A table lock never keeps other users from querying a table, and a query never acquires a
table lock. Only if two different transactions try to modify the same row will one
transaction wait for the other to complete.
Fetching Across Commits
PL/SQL raises an exception if you try to fetch from a FOR UPDATE cursor after doing a
commit. The FOR UPDATE clause locks the rows when you open the cursor, and unlocks
them when you commit.
DECLARE
CURSOR c1 IS SELECT ename FROM emp FOR UPDATE OF sal;
BEGIN
FOR emp_rec IN c1 LOOP -- FETCH fails on the second iteration
INSERT INTO temp VALUES ('still going');
COMMIT; -- releases locks
END LOOP;
END;

If you want to fetch across commits, use the ROWID pseudocolumn to mimic the CURRENT
OF clause. Select the rowid of each row into a UROWID variable, then use the rowid to
identify the current row during subsequent updates and deletes:
DECLARE
CURSOR c1 IS SELECT ename, job, rowid FROM emp;
my_ename emp.ename%TYPE;
my_job emp.job%TYPE;
my_rowid UROWID;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO my_ename, my_job, my_rowid;
EXIT WHEN c1%NOTFOUND;
UPDATE emp SET sal = sal * 1.05 WHERE rowid = my_rowid;

By Subhash Reddy Aedla Page 244 of 304


ORACLE

-- this mimics WHERE CURRENT OF c1


COMMIT;
END LOOP;
CLOSE c1;
END;

Because the fetched rows are not locked by a FOR UPDATE clause, other users might
unintentionally overwrite your changes. The extra space needed for read consistency is
not released until the cursor is closed, which can slow down processing for large
updates.
The next example shows that you can use the %ROWTYPE attribute with cursors that
reference the ROWID pseudocolumn:
DECLARE
CURSOR c1 IS SELECT ename, sal, rowid FROM emp;
emp_rec c1%ROWTYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO emp_rec;
EXIT WHEN c1%NOTFOUND;
IF ... THEN
DELETE FROM emp WHERE rowid = emp_rec.rowid;
END IF;
END LOOP;
CLOSE c1;
END;
Using PL/SQL Subprograms

Database Triggers

A database triggers is stored PL/SQL program unit associated with a specific database
table or view. The code in the trigger defines the action the database needs to perform
whenever some database manipulation (INSERT, UPDATE, DELETE) takes place.

Unlike the stored procedure and functions, which have to be called explicitly, the
database triggers are fires (executed) or called implicitly whenever the table is affected
by any of the above said DML operations.

By Subhash Reddy Aedla Page 245 of 304


ORACLE

Till oracle 7.0 only 12 triggers could be associated with a given table, but in higher
versions of Oracle there is no such limitation. A database trigger fires with the privileges
of owner not that of user

A database trigger has three parts

1. A triggering event
2. A trigger constraint (Optional)
3. Trigger action

A triggering event can be an insert, update, or delete statement or a instance shutdown


or startup etc. The trigger fires automatically when any of these events occur A trigger
constraint specifies a Boolean expression that must be true for the trigger to fire. This
condition is specified using the WHEN clause. The trigger action is a procedure that
contains the code to be executed when the trigger fires.

Types of Triggers

The following are the different types of triggers.

Row triggers and statement triggers

A Row trigger fires once for each row affected. It uses FOR EACH ROW clause. They are
useful if trigger action depends on number of rows affected.

Statement Trigger fires once, irrespective of number of rows affected in the table.
Statement triggers are useful when triggers action does not depend on

Before and afterTriggers

While defining the trigger we can specify whether to perform the trigger action (i.e.
execute trigger body) before or after the triggering statement. BEFORE and AFTER
triggers fired by DML statements can only be defined on tables.

BEFORE triggers The trigger action here is run before the trigger statement.

AFTER triggers The trigger action here is run after the trigger statement.

INSTEAD of Triggers provide a way of modifying views that can not be modified directly
using DML statements.

LOGON triggers fires after successful logon by the user and LOGOFF trigger fires at the
start of user logoff.

By Subhash Reddy Aedla Page 246 of 304


ORACLE

Points to ponder

 A trigger cannot include COMMIT, SAVEPOINT and ROLLBACK.


 We can use only one trigger of a particular type .
 A table can have any number of triggers.
 We use correlation names :new and :old can be used to refer to data in
command line and data in table respectively.

Triggers on DDL statements

DDL trigger are of the following types

BEFORE CREATE OR AFTER CREATE trigger is fired when a schema object is created.
BEFORE OR AFTER ALTER trigger is fired when a schema object is altered.
BEFORE OR AFTER DROP trigger is fired when a schema object is dropped.

A trigger can be enabled means can be made to run or it can disabled means it cannot
run. A trigger is automatically enabled when it is created. We need re-enable trigger for
using it if it is disabled. To enable or disable a trigger using ALTER TRIGGER command,
you must be owner of the trigger or should have ALTER ANY TRIGGER privilege. To
create a trigger you must have CREATE TRIGGER privilege, which is given to as part of
RESOURCE privilege at the time of user creation.

Following figures give more understanding about triggers

By Subhash Reddy Aedla Page 247 of 304


ORACLE

By Subhash Reddy Aedla Page 248 of 304


ORACLE

Handling multiple situations

A trigger can be used to handle multiple situations as shown in the following example.
By using conditional predicates UPDATING, INSERTING, or DELETING we can handle each
situation.

By Subhash Reddy Aedla Page 249 of 304


ORACLE

CORRELATION NAMES

While using row triggers, the trigger action statement can access column values of the
row that is being processed currently. This is done using correlation names. There exist
two correlation names for every column of the table, one for the column old value and

By Subhash Reddy Aedla Page 250 of 304


ORACLE

the other for its new value. We use qualifier NEW with column name for new values and
qualifier OLD is used to refer old value of the column.

Example:

IF :new.sal < :old.sal THEN


……

The REFERENCING option is used to avoid name conflicts between correlation names
and table names. For example if you are using a table by name new or old with field
names say SNO, NAME (though it is a very rare situation) then the ambiguity arises. To
avoid this we use REFERENCING option.

Mutating Table: is a table that is presently under modification by INSERT, UPDATE, or


DELETE statement, or a table that has referential integrity constraint with DELETE
CASCADE OPTION.

Constraining Table: is a table, which is to be read by triggering statement either directly


or indirectly.

By Subhash Reddy Aedla Page 251 of 304


ORACLE

In the above example when we tried to delete a row using SQL statement (Mutating
Table) , which fires AFTER DELETE trigger. The body of this trigger is having a select
statement that tries to read the table. This operation is not allowed by oracle. Hence we
received a runtime error and total action is rolled back by Oracle. (The row is not
deleted)

Handling multiple situations

A trigger can be used to handle multiple situations as shown in the following example.
By using conditional predicates UPDATING, INSERTING, or DELETING we can handle each
situation.

By Subhash Reddy Aedla Page 252 of 304


ORACLE

CORRELATION NAMES

While using row triggers, the trigger action statement can access column values of the
row that is being processed currently. This is done using correlation names. There exist
two correlation names for every column of the table, one for the column old value and

By Subhash Reddy Aedla Page 253 of 304


ORACLE

the other for its new value. We use qualifier NEW with column name for new values and
qualifier OLD is used to refer old value of the column.

Example:

IF :new.sal < :old.sal THEN


……

The REFERENCING option is used to avoid name conflicts between correlation names
and table names. For example if you are using a table by name new or old with field
names say SNO, NAME (though it is a very rare situation) then the ambiguity arises. To
avoid this we use REFERENCING option.

Mutating Table: is a table that is presently under modification by INSERT, UPDATE, or


DELETE statement, or a table that has referential integrity constraint with DELETE
CASCADE OPTION.

Constraining Table: is a table, which is to be read by triggering statement either directly


or indirectly.

By Subhash Reddy Aedla Page 254 of 304


ORACLE

In the above example when we tried to delete a row using SQL statement (Mutating
Table) , which fires AFTER DELETE trigger. The body of this trigger is having a select
statement that tries to read the table. This operation is not allowed by oracle. Hence we
received a runtime error and total action is rolled back by Oracle. (The row is not
deleted)

CREATE OR REPLACE TRIGGER MYTRIG2


BEFORE UPDATE OR INSERT OR DELETE ON EMP
FOR EACH ROW
BEGIN
IF UPDATING THEN
DBMS_OUTPUT.PUT_LINE('Updating the table');
ELSIF INSERTING THEN
DBMS_OUTPUT.PUT_LINE('Inserting record into table');
ELSIF DELETING THEN
DBMS_OUTPUT.PUT_LINE('Deleting record from table');
END IF;
END;
/

By Subhash Reddy Aedla Page 255 of 304


ORACLE

CREATE OR REPLACE TRIGGER MYTRIG1


BEFORE INSERT OR DELETE OR UPDATE ON EMP
FOR EACH ROW

BEGIN
IF TO_CHAR(SYSDATE,'DY') = 'SUN' THEN
DBMS_OUTPUT.PUT_LINE('Today is Holiday ...');
ELSE
DBMS_OUTPUT.PUT_LINE('Welcome back ....');
END IF;
END;
/

CREATE OR REPLACE TRIGGER MYTRIG3


AFTER DELETE ON EMP
FOR EACH ROW

DECLARE
N NUMBER(3);
BEGIN
SELECT COUNT(*) INTO N FROM emp;
DBMS_OUTPUT.PUT_LINE('No of Employees='||N);
END;

This tutorial covers Defining and Using Collections - Declaring, Initializing, and
Referencing PL/SQL Collections and Collection Methods - Using the Collection Methods.
Subprograms
Subprograms are named PL/SQL blocks that can be called with a set of parameters.
PL/SQL has two types of subprograms, procedures and functions. Generally, you use a
procedure to perform an action and a function to compute a value.
Like anonymous blocks, subprograms have:
 A declarative part, with declarations of types, cursors, constants, variables,
exceptions, and nested subprograms. These items are local and cease to exist
when the subprogram ends.

By Subhash Reddy Aedla Page 256 of 304


ORACLE

 An executable part, with statements that assign values, control execution, and
manipulate Oracle data.
 An optional exception-handling part, which deals with runtime error conditions.
Example - Simple PL/SQL Procedure
The following example shows a string-manipulation procedure that accepts both input
and output parameters, and handles potential errors:
CREATE OR REPLACE PROCEDURE double
(
original IN VARCHAR2, new_string OUT VARCHAR2
)
AS
BEGIN
new_string := original || original;
EXCEPTION
WHEN VALUE_ERROR THEN
dbms_output.put_line('Output buffer not long enough.');
END;
/
Example - Simple PL/SQL Function
The following example shows a numeric function that declares a local variable to hold
temporary results, and returns a value when finished:
CREATE OR REPLACE FUNCTION square(original NUMBER)
RETURN NUMBER
AS
original_squared NUMBER;
BEGIN
original_squared := original * original;
RETURN original_squared;
END;
/
Advantages of PL/SQL Subprograms
Subprograms let you extend the PL/SQL language. Procedures act like new statements.
Functions act like new expressions and operators.
Subprograms let you break a program down into manageable, well-defined modules.
You can use top-down design and the stepwise refinement approach to problem solving.

By Subhash Reddy Aedla Page 257 of 304


ORACLE

Subprograms promote reusability. Once tested, a subprogram can be reused in any


number of applications. You can call PL/SQL subprograms from many different
environments, so that you do not have to reinvent the wheel each time you use a new
language or API to access the database.
Subprograms promote maintainability. You can change the internals of a subprogram
without changing other subprograms that call it. Subprograms play a big part in other
maintainability features, such as packages and object types.
Dummy subprograms (stubs) let you defer the definition of procedures and functions
until after testing the main program. You can design applications from the top down,
thinking abstractly, without worrying about implementation details.
When you use PL/SQL subprograms to define an API, you can make your code even
more reusable and maintainable by grouping the subprograms into a PL/SQL package
Understanding PL/SQL Procedures
A procedure is a subprogram that performs a specific action. You write procedures using
the SQL CREATE PROCEDURE statement. You specify the name of the procedure, its
parameters, its local variables, and the BEGIN-END block that contains its code and
handles any exceptions.
For each parameter, you specify:
 Its name.
 Its parameter mode (IN, OUT, or IN OUT). If you omit the mode, the default is IN.
The optional NOCOPY keyword speeds up processing of large OUT or IN OUT
parameters.
 Its datatype. You specify only the type, not any length or precision constraints.
 Optionally, its default value.
You can specify whether the procedure executes using the schema and permissions of
the user who defined it, or the user who calls it.
You can specify whether it should be part of the current transaction, or execute in its
own transaction where it can COMMIT or ROLLBACK without ending the transaction of the
caller.
Procedures created this way are stored in the database. You can execute the CREATE
PROCEDURE statement interactively from SQL*Plus, or from a program using native
dynamic SQL.

By Subhash Reddy Aedla Page 258 of 304


ORACLE

A procedure has two parts: the specification (spec for short) and the body. The
procedure spec begins with the keyword PROCEDURE and ends with the procedure name
or a parameter list. Parameter declarations are optional. Procedures that take no
parameters are written without parentheses.
The procedure body begins with the keyword IS (or AS) and ends with the keyword END
followed by an optional procedure name. The procedure body has three parts: a
declarative part, an executable part, and an optional exception-handling part.
The declarative part contains local declarations. The keyword DECLARE is used for
anonymous PL/SQL blocks, but not procedures. The executable part contains
statements, which are placed between the keywords BEGIN and EXCEPTION (or END). At
least one statement must appear in the executable part of a procedure. You can use the
NULL statement to define a placeholder procedure or specify that the procedure does
nothing. The exception-handling part contains exception handlers, which are placed
between the keywords EXCEPTION and END.
A procedure is called as a PL/SQL statement. For example, you might call the procedure
raise_salary as follows:

raise_salary(emp_id, amount);
Understanding PL/SQL Functions
A function is a subprogram that computes a value. Functions and procedures are
structured alike, except that functions have a RETURN clause.
Functions have a number of optional keywords, used to declare a special class of
functions known as table functions. They are typically used for transforming large
amounts of data in data warehousing applications.
The CREATE clause lets you create standalone functions, which are stored in an Oracle
database. You can execute the CREATE FUNCTION statement interactively from SQL*Plus or
from a program using native dynamic SQL.
The AUTHID clause determines whether a stored function executes with the privileges of
its owner (the default) or current user and whether its unqualified references to schema
objects are resolved in the schema of the owner or current user. You can override the
default behavior by specifying CURRENT_USER.
The PARALLEL_ENABLE option declares that a stored function can be used safely in the
slave sessions of parallel DML evaluations. The state of a main (logon) session is never
shared with slave sessions. Each slave session has its own state, which is initialized when
the session begins. The function result should not depend on the state of session (static)
variables. Otherwise, results might vary across sessions.

By Subhash Reddy Aedla Page 259 of 304


ORACLE

The hint DETERMINISTIC helps the optimizer avoid redundant function calls. If a stored
function was called previously with the same arguments, the optimizer can elect to use
the previous result. The function result should not depend on the state of session
variables or schema objects. Otherwise, results might vary across calls. Only
DETERMINISTIC functions can be called from a function-based index or a materialized view
that has query-rewrite enabled. For more information, see Oracle Database SQL
Reference.
The pragma AUTONOMOUS_TRANSACTION instructs the PL/SQL compiler to mark a function
as autonomous (independent). Autonomous transactions let you suspend the main
transaction, do SQL operations, commit or roll back those operations, then resume the
main transaction.
You cannot constrain (with NOT NULL for example) the datatype of a parameter or a
function return value. However, you can use a workaround to size-constrain them
indirectly.
Like a procedure, a function has two parts: the spec and the body. The function spec
begins with the keyword FUNCTION and ends with the RETURN clause, which specifies the
datatype of the return value. Parameter declarations are optional. Functions that take
no parameters are written without parentheses.
The function body begins with the keyword IS (or AS) and ends with the keyword END
followed by an optional function name. The function body has three parts: a declarative
part, an executable part, and an optional exception-handling part.
The declarative part contains local declarations, which are placed between the
keywords IS and BEGIN. The keyword DECLARE is not used. The executable part contains
statements, which are placed between the keywords BEGIN and EXCEPTION (or END). One
or more RETURN statements must appear in the executable part of a function. The
exception-handling part contains exception handlers, which are placed between the
keywords EXCEPTION and END.
A function is called as part of an expression:
IF sal_ok(new_sal, new_title) THEN ...
Using the RETURN Statement
The RETURN statement immediately ends the execution of a subprogram and returns
control to the caller. Execution continues with the statement following the subprogram
call. (Do not confuse the RETURN statement with the RETURN clause in a function spec,
which specifies the datatype of the return value.)

By Subhash Reddy Aedla Page 260 of 304


ORACLE

A subprogram can contain several RETURN statements. The subprogram does not have to
conclude with a RETURN statement. Executing any RETURN statement completes the
subprogram immediately.
In procedures, a RETURN statement does not return a value and so cannot contain an
expression. The statement returns control to the caller before the end of the procedure.
In functions, a RETURN statement must contain an expression, which is evaluated when
the RETURN statement is executed. The resulting value is assigned to the function
identifier, which acts like a variable of the type specified in the RETURN clause. Observe
how the function balance returns the balance of a specified bank account:
FUNCTION balance (acct_id INTEGER) RETURN REAL IS
acct_bal REAL;
BEGIN
SELECT bal INTO acct_bal FROM accts
WHERE acct_no = acct_id;
RETURN acct_bal;
END balance;
/
The following example shows that the expression in a function RETURN statement can be
arbitrarily complex:
FUNCTION compound (
years NUMBER,
amount NUMBER,
rate NUMBER) RETURN NUMBER IS
BEGIN
RETURN amount * POWER((rate / 100) + 1, years);
END compound;
/
In a function, there must be at least one execution path that leads to a RETURN
statement. Otherwise, you get a function returned without value error at run time.
Declaring Nested PL/SQL Subprograms
You can declare subprograms in any PL/SQL block, subprogram, or package. The
subprograms must go at the end of the declarative section, after all other items.
You must declare a subprogram before calling it. This requirement can make it difficult
to declare several nested subprograms that call each other.

By Subhash Reddy Aedla Page 261 of 304


ORACLE

You can declare interrelated nested subprograms using a forward declaration: a


subprogram spec terminated by a semicolon, with no body.
Although the formal parameter list appears in the forward declaration, it must also
appear in the subprogram body. You can place the subprogram body anywhere after the
forward declaration, but they must appear in the same program unit.
Example - Forward Declaration for a Nested Subprogram
DECLARE
PROCEDURE proc1(arg_list); -- forward declaration
PROCEDURE proc2(arg_list); -- calls proc1
PROCEDURE proc1(arg_list) IS BEGIN proc2; END; -- calls proc2
BEGIN
NULL;
END;
/
Passing Parameters to PL/SQL Subprograms
This section explains how to pass information in and out of PL/SQL subprograms using
parameters:
 Actual Versus Formal Subprogram Parameters
 Using Positional, Named, or Mixed Notation for Subprogram Parameters
 Specifying Subprogram Parameter Modes
 Using Default Values for Subprogram Parameters
Actual Versus Formal Subprogram Parameters
Subprograms pass information using parameters:
 The variables declared in a subprogram spec and referenced in the subprogram
body are formal parameters.
 The variables or expressions passed from the calling subprogram are actual
parameters.
A good programming practice is to use different names for actual and formal
parameters.
When you call a procedure, the actual parameters are evaluated and the results are
assigned to the corresponding formal parameters. If necessary, before assigning the
value of an actual parameter to a formal parameter, PL/SQL converts the datatype of

By Subhash Reddy Aedla Page 262 of 304


ORACLE

the value. For example, if you pass a number when the procedure expects a string,
PL/SQL converts the parameter so that the procedure receives a string.
The actual parameter and its corresponding formal parameter must have compatible
datatypes. For instance, PL/SQL cannot convert between the DATE and REAL datatypes, or
convert a string to a number if the string contains extra characters such as dollar signs.
Example - Formal Parameters and Actual Parameters
The following procedure declares two formal parameters named emp_id and amount:
PROCEDURE raise_salary (emp_id INTEGER, amount REAL) IS
BEGIN
UPDATE emp SET sal = sal + amount WHERE empno = emp_id;
END raise_salary;
/
This procedure call specifies the actual parameters emp_num and amount:
raise_salary(emp_num, amount);
Expressions can be used as actual parameters:
raise_salary(emp_num, merit + cola);
Using Positional, Named, or Mixed Notation for Subprogram Parameters
When calling a subprogram, you can write the actual parameters using either:
 Positional notation. You specify the same parameters in the same order as they
are declared in the procedure.
This notation is compact, but if you specify the parameters (especially literals) in
the wrong order, the bug can be hard to detect. You must change your code if
the procedure's parameter list changes.
 Named notation. You specify the name of each parameter along with its value.
An arrow (=>) serves as the association operator. The order of the parameters is
not significant.
This notation is more verbose, but makes your code easier to read and maintain.
You can sometimes avoid changing your code if the procedure's parameter list
changes, for example if the parameters are reordered or a new optional
parameter is added. Named notation is a good practice to use for any code that
calls someone else's API, or defines an API for someone else to use.

By Subhash Reddy Aedla Page 263 of 304


ORACLE

 Mixed notation. You specify the first parameters with positional notation, then
switch to named notation for the last parameters.
You can use this notation to call procedures that have some required
parameters, followed by some optional parameters.
Example - Subprogram Calls Using Positional, Named, and Mixed Notation
DECLARE
acct INTEGER := 12345;
amt REAL := 500.00;
PROCEDURE credit_acct (acct_no INTEGER, amount REAL) IS
BEGIN NULL; END;
BEGIN
-- The following calls are all equivalent.
credit_acct(acct, amt); -- positional
credit_acct(amount => amt, acct_no => acct); -- named
credit_acct(acct_no => acct, amount => amt); -- named
credit_acct(acct, amount => amt); -- mixed
END;
/
Specifying Subprogram Parameter Modes
You use parameter modes to define the behavior of formal parameters. The three
parameter modes are IN (the default), OUT, and IN OUT.
Any parameter mode can be used with any subprogram. Avoid using the OUT and IN OUT
modes with functions. To have a function return multiple values is a poor programming
practice. Also, functions should be free from side effects, which change the values of
variables not local to the subprogram.

Using the IN Mode


An IN parameter lets you pass values to the subprogram being called. Inside the
subprogram, an IN parameter acts like a constant. It cannot be assigned a value.
You can pass a constant, literal, initialized variable, or expression as an IN parameter.
IN parameters can be initialized to default values, which are used if those parameters
are omitted from the subprogram call.

By Subhash Reddy Aedla Page 264 of 304


ORACLE

Using the OUT Mode


An OUT parameter returns a value to the caller of a subprogram. Inside the subprogram,
an OUT parameter acts like a variable. You can change its value, and reference the value
after assigning it:
PROCEDURE split_name
(
phrase IN VARCHAR2, first OUT VARCHAR2, last OUT VARCHAR2
)
IS
first := SUBSTR(phrase, 1, INSTR(phrase, ' ')-1);
last := SUBSTR(phrase, INSTR(phrase, ' ')+1);
IF first = 'John' THEN
DBMS_OUTPUT.PUT_LINE('That is a common first name.');
END IF;
END;
/
You must pass a variable, not a constant or an expression, to an OUT parameter. Its
previous value is lost unless you specify the NOCOPY keyword or the subprogram exits
with an unhandled exception.
Like variables, OUT formal parameters are initialized to NULL. The datatype of an OUT
formal parameter cannot be a subtype defined as NOT NULL, such as the built-in subtypes
NATURALN and POSITIVEN. Otherwise, when you call the subprogram, PL/SQL raises
VALUE_ERROR.

Before exiting a subprogram, assign values to all OUT formal parameters. Otherwise, the
corresponding actual parameters will be null. If you exit successfully, PL/SQL assigns
values to the actual parameters. If you exit with an unhandled exception, PL/SQL does
not assign values to the actual parameters.

Using the IN OUT Mode


An IN OUT parameter passes initial values to a subprogram and returns updated values to
the caller. It can be assigned a value and its value can be read. Typically, an IN OUT
parameter is a string buffer or numeric accumulator, that is read inside the subprogram
and then updated.
The actual parameter that corresponds to an IN OUT formal parameter must be a
variable; it cannot be a constant or an expression.

By Subhash Reddy Aedla Page 265 of 304


ORACLE

If you exit a subprogram successfully, PL/SQL assigns values to the actual parameters. If
you exit with an unhandled exception, PL/SQL does not assign values to the actual
parameters.

Summary of Subprogram Parameter Modes


Table summarizes all you need to know about the parameter modes.
Table Parameter Modes

IN OUT IN OUT

The default Must be specified Must be specified

Passes values to a Returns values to the caller Passes initial values to a


subprogram subprogram and returns
updated values to the caller

Formal parameter acts Formal parameter acts like Formal parameter acts like an
like a constant an uninitialized variable initialized variable

Formal parameter Formal parameter must be Formal parameter should be


cannot be assigned a assigned a value assigned a value
value

Actual parameter can be Actual parameter must be a Actual parameter must be a


a constant, initialized variable variable
variable, literal, or
expression

Actual parameter is Actual parameter is passed Actual parameter is passed by


passed by reference (a by value (a copy of the value value (a copy of the value is
pointer to the value is is passed out) unless NOCOPY passed in and out) unless
passed in) is specified NOCOPY is specified

Using Default Values for Subprogram Parameters


By initializing IN parameters to default values, you can pass different numbers of actual
parameters to a subprogram, accepting the default values for any parameters you omit.
You can also add new formal parameters without having to change every call to the
subprogram.
Example - Procedure with Default Parameter Values
PROCEDURE create_dept (

By Subhash Reddy Aedla Page 266 of 304


ORACLE

new_dname VARCHAR2 DEFAULT 'TEMP',


new_loc VARCHAR2 DEFAULT 'TEMP') IS
BEGIN
NULL;
END;
/
If a parameter is omitted, the default value of its corresponding formal parameter is
used. Consider the following calls to create_dept:
create_dept; -- Same as create_dept('TEMP','TEMP');
create_dept('SALES'); -- Same as create_dept('SALES','TEMP');
create_dept('SALES', 'NY');
You cannot skip a formal parameter by leaving out its actual parameter. To omit the first
parameter and specify the second, use named notation:
create_dept(new_loc => 'NEW YORK');
You cannot assign a null to an uninitialized formal parameter by leaving out its actual
parameter. You must pass the null explicitly, or you can specify a default value of NULL in
the declaration.
Overloading Subprogram Names
PL/SQL lets you overload subprogram names and type methods. You can use the same
name for several different subprograms as long as their formal parameters differ in
number, order, or datatype family.
Suppose you want to initialize the first n rows in two index-by tables that were declared
as follows:
DECLARE
TYPE DateTabTyp IS TABLE OF DATE INDEX BY BINARY_INTEGER;
TYPE RealTabTyp IS TABLE OF REAL INDEX BY BINARY_INTEGER;
hiredate_tab DateTabTyp;
sal_tab RealTabTyp;
BEGIN
NULL;
END;
/
You might write a procedure to initialize one kind of collection:
PROCEDURE initialize (tab OUT DateTabTyp, n INTEGER) IS

By Subhash Reddy Aedla Page 267 of 304


ORACLE

BEGIN
FOR i IN 1..n LOOP
tab(i) := SYSDATE;
END LOOP;
END initialize;
/
You might also write a procedure to initialize another kind of collection:
PROCEDURE initialize (tab OUT RealTabTyp, n INTEGER) IS
BEGIN
FOR i IN 1..n LOOP
tab(i) := 0.0;
END LOOP;
END initialize;
/
Because the processing in these two procedures is the same, it is logical to give them
the same name.
You can place the two overloaded initialize procedures in the same block, subprogram,
package, or object type. PL/SQL determines which procedure to call by checking their
formal parameters. In the following example, the version of initialize that PL/SQL uses
depends on whether you call the procedure with a DateTabTyp or RealTabTyp parameter:
DECLARE
TYPE DateTabTyp IS TABLE OF DATE INDEX BY BINARY_INTEGER;
TYPE RealTabTyp IS TABLE OF REAL INDEX BY BINARY_INTEGER;
hiredate_tab DateTabTyp;
comm_tab RealTabTyp;
indx BINARY_INTEGER;
PROCEDURE initialize (tab OUT DateTabTyp, n INTEGER) IS
BEGIN
NULL;
END;
PROCEDURE initialize (tab OUT RealTabTyp, n INTEGER) IS
BEGIN
NULL;
END;
BEGIN
indx := 50;
initialize(hiredate_tab, indx); -- calls first version

By Subhash Reddy Aedla Page 268 of 304


ORACLE

initialize(comm_tab, indx); -- calls second version


END;
/

By Subhash Reddy Aedla Page 269 of 304


ORACLE

Using PL/SQL Packages


PL/SQL Package
A package is a schema object that groups logically related PL/SQL types, variables, and
subprograms. Packages usually have two parts, a specification and a body; sometimes
the body is unnecessary. The specification (spec for short) is the interface to the
package. It declares the types, variables, constants, exceptions, cursors, and
subprograms that can be referenced from outside the package. The body defines the
queries for the cursors and the code for the subprograms.
You can think of the spec as an interface and of the body as a "black box." You can
debug, enhance, or replace a package body without changing the package spec.
To create package specs, use the SQL statement CREATE PACKAGE. If necessary, a CREATE
PACKAGE BODY statement defines the package body.

The spec holds public declarations, which are visible to stored procedures and other
code outside the package. You must declare subprograms at the end of the spec after all
other items (except pragmas that name a specific function; such pragmas must follow
the function spec).
The body holds implementation details and private declarations, which are hidden from
code outside the package. Following the declarative part of the package body is the
optional initialization part, which holds statements that initialize package variables and
do any other one-time setup steps.
The AUTHID clause determines whether all the packaged subprograms execute with the
privileges of their definer (the default) or invoker, and whether their unqualified
references to schema objects are resolved in the schema of the definer or invoker.
A call spec lets you map a package subprogram to a Java method or external C function.
The call spec maps the Java or C name, parameter types, and return type to their SQL
counterparts. To learn how to write Java call specs, see Oracle Database Java
Developer's Guide. To learn how to write C call specs, see Oracle Database Application
Developer's Guide - Fundamentals.
What Goes In a PL/SQL Package?
 "Get" and "Set" methods for the package variables, if you want to avoid letting
other procedures read and write them directly.
 Cursor declarations with the text of SQL queries. Reusing exactly the same query
text in multiple locations is faster than retyping the same query each time with

By Subhash Reddy Aedla Page 270 of 304


ORACLE

slight differences. It is also easier to maintain if you need to change a query that
is used in many places.
 Declarations for exceptions. Typically, you need to be able to reference these
from different procedures, so that you can handle exceptions within called
subprograms.
 Declarations for procedures and functions that call each other. You do not need
to worry about compilation order for packaged procedures and functions,
making them more convenient than standalone stored procedures and functions
when they call back and forth to each other.
 Declarations for overloaded procedures and functions. You can create multiple
variations of a procedure or function, using the same names but different sets of
parameters.
 Variables that you want to remain available between procedure calls in the same
session. You can treat variables in a package like global variables.
 Type declarations for PL/SQL collection types. To pass a collection as a
parameter between stored procedures or functions, you must declare the type
in a package so that both the calling and called subprogram can refer to it.
Example of a PL/SQL Package
The example below packages a record type, a cursor, and two employment procedures.
The procedure hire_employee uses the sequence empno_seq and the function SYSDATE to
insert a new employee number and hire date.
CREATE OR REPLACE PACKAGE emp_actions AS -- spec
TYPE EmpRecTyp IS RECORD (emp_id INT, salary REAL);
CURSOR desc_salary RETURN EmpRecTyp;
PROCEDURE hire_employee (
ename VARCHAR2,
job VARCHAR2,
mgr NUMBER,
sal NUMBER,
comm NUMBER,
deptno NUMBER);
PROCEDURE fire_employee (emp_id NUMBER);
END emp_actions;
/

CREATE OR REPLACE PACKAGE BODY emp_actions AS -- body

By Subhash Reddy Aedla Page 271 of 304


ORACLE

CURSOR desc_salary RETURN EmpRecTyp IS


SELECT empno, sal FROM emp ORDER BY sal DESC;
PROCEDURE hire_employee (
ename VARCHAR2,
job VARCHAR2,
mgr NUMBER,
sal NUMBER,
comm NUMBER,
deptno NUMBER) IS
BEGIN
INSERT INTO emp VALUES (empno_seq.NEXTVAL, ename, job,
mgr, SYSDATE, sal, comm, deptno);
END hire_employee;

PROCEDURE fire_employee (emp_id NUMBER) IS


BEGIN
DELETE FROM emp WHERE empno = emp_id;
END fire_employee;
END emp_actions;
/
Only the declarations in the package spec are visible and accessible to applications.
Implementation details in the package body are hidden and inaccessible. You can
change the body (implementation) without having to recompile calling programs.
Advantages of PL/SQL Packages
Packages have a long history in software engineering, offering important features for
reliable, maintainable, reusable code, often in team development efforts for large
systems.
Modularity
Packages let you encapsulate logically related types, items, and subprograms in a named
PL/SQL module. Each package is easy to understand, and the interfaces between
packages are simple, clear, and well defined. This aids application development.
Easier Application Design
When designing an application, all you need initially is the interface information in the
package specs. You can code and compile a spec without its body. Then, stored
subprograms that reference the package can be compiled as well. You need not define
the package bodies fully until you are ready to complete the application.

By Subhash Reddy Aedla Page 272 of 304


ORACLE

Information Hiding
With packages, you can specify which types, items, and subprograms are public (visible
and accessible) or private (hidden and inaccessible). For example, if a package contains
four subprograms, three might be public and one private. The package hides the
implementation of the private subprogram so that only the package (not your
application) is affected if the implementation changes. This simplifies maintenance and
enhancement. Also, by hiding implementation details from users, you protect the
integrity of the package.
Added Functionality
Packaged public variables and cursors persist for the duration of a session. They can be
shared by all subprograms that execute in the environment. They let you maintain data
across transactions without storing it in the database.
Better Performance
When you call a packaged subprogram for the first time, the whole package is loaded
into memory. Later calls to related subprograms in the package require no disk I/O.
Packages stop cascading dependencies and avoid unnecessary recompiling. For
example, if you change the body of a packaged function, Oracle does not recompile
other subprograms that call the function; these subprograms only depend on the
parameters and return value that are declared in the spec, so they are only recompiled
if the spec changes.
Understanding The Package Specification
The package specification contains public declarations. The declared items are
accessible from anywhere in the package and to any other subprograms in the same
schema.
Figure - Package Scope

By Subhash Reddy Aedla Page 273 of 304


ORACLE

The spec lists the package resources available to applications. All the information your
application needs to use the resources is in the spec. For example, the following
declaration shows that the function named fac takes one argument of type INTEGER and
returns a value of type INTEGER:
FUNCTION fac (n INTEGER) RETURN INTEGER; -- returns n!
That is all the information you need to call the function. You need not consider its
underlying implementation (whether it is iterative or recursive for example).
If a spec declares only types, constants, variables, exceptions, and call specs, the
package body is unnecessary. Only subprograms and cursors have an underlying
implementation. In the following example, the package needs no body because it
declares types, exceptions, and variables, but no subprograms or cursors. Such packages
let you define global variables—usable by stored procedures and functions and
triggers—that persist throughout a session.
CREATE PACKAGE trans_data AS -- bodiless package
TYPE TimeRec IS RECORD (
minutes SMALLINT,
hours SMALLINT);
TYPE TransRec IS RECORD (
category VARCHAR2,
account INT,
amount REAL,
time_of TimeRec);
minimum_balance CONSTANT REAL := 10.00;
number_processed INT;
insufficient_funds EXCEPTION;
END trans_data;
/

By Subhash Reddy Aedla Page 274 of 304


ORACLE

Referencing Package Contents


To reference the types, items, subprograms, and call specs declared within a package
spec, use dot notation:
package_name.type_name
package_name.item_name
package_name.subprogram_name
package_name.call_spec_name
You can reference package contents from database triggers, stored subprograms, 3GL
application programs, and various Oracle tools. For example, you might call the
packaged procedure hire_employee from SQL*Plus, as follows:
CALL emp_actions.hire_employee('TATE', 'CLERK', ...);
The following example calls the same procedure from an anonymous block in a Pro*C
program. The actual parameters emp_name and job_title are host variables.
EXEC SQL EXECUTE
BEGIN
emp_actions.hire_employee(:emp_name, :job_title, ...);

Restrictions
You cannot reference remote packaged variables, either directly or indirectly. For
example, you cannot call the a procedure through a database link if the procedure refers
to a packaged variable.
Inside a package, you cannot reference host variables.
Understanding the Package Body
The package body contains the implementation of every cursor and subprogram
declared in the package spec. Subprograms defined in a package body are accessible
outside the package only if their specs also appear in the package spec. If a subprogram
spec is not included in the package spec, that subprogram can only be called by other
subprograms in the same package.
To match subprogram specs and bodies, PL/SQL does a token-by-token comparison of
their headers. Except for white space, the headers must match word for word.
Otherwise, PL/SQL raises an exception, as the following example shows:
CREATE PACKAGE emp_actions AS
...

By Subhash Reddy Aedla Page 275 of 304


ORACLE

PROCEDURE calc_bonus (date_hired emp.hiredate%TYPE, ...);


END emp_actions;
/

CREATE PACKAGE BODY emp_actions AS


...
PROCEDURE calc_bonus (date_hired DATE, ...) IS
-- parameter declaration raises an exception because 'DATE'
-- does not match 'emp.hiredate%TYPE' word for word
BEGIN ... END;
END emp_actions;
/
The package body can also contain private declarations, which define types and items
necessary for the internal workings of the package. The scope of these declarations is
local to the package body. Therefore, the declared types and items are inaccessible
except from within the package body. Unlike a package spec, the declarative part of a
package body can contain subprogram bodies.
Following the declarative part of a package body is the optional initialization part, which
typically holds statements that initialize some of the variables previously declared in the
package.
The initialization part of a package plays a minor role because, unlike subprograms, a
package cannot be called or passed parameters. As a result, the initialization part of a
package is run only once, the first time you reference the package.
Remember, if a package spec declares only types, constants, variables, exceptions, and
call specs, the package body is unnecessary. However, the body can still be used to
initialize items declared in the package spec.
Some Examples of Package Features
Consider the following package, named emp_actions. The package spec declares the
following types, items, and subprograms:
 Types EmpRecTyp and DeptRecTyp
 Cursor desc_salary
 Exception invalid_salary
 Functions hire_employee and nth_highest_salary
 Procedures fire_employee and raise_salary

By Subhash Reddy Aedla Page 276 of 304


ORACLE

After writing the package, you can develop applications that reference its types, call its
subprograms, use its cursor, and raise its exception. When you create the package, it is
stored in an Oracle database for use by any application that has execute privilege on the
package.
CREATE PACKAGE emp_actions AS
/* Declare externally visible types, cursor, exception. */
TYPE EmpRecTyp IS RECORD (emp_id INT, salary REAL);
TYPE DeptRecTyp IS RECORD (dept_id INT, location VARCHAR2);
CURSOR desc_salary RETURN EmpRecTyp;
invalid_salary EXCEPTION;

/* Declare externally callable subprograms. */


FUNCTION hire_employee (
ename VARCHAR2,
job VARCHAR2,
mgr REAL,
sal REAL,
comm REAL,
deptno REAL) RETURN INT;
PROCEDURE fire_employee (emp_id INT);
PROCEDURE raise_salary (emp_id INT, grade INT, amount REAL);
FUNCTION nth_highest_salary (n INT) RETURN EmpRecTyp;
END emp_actions;
/

CREATE PACKAGE BODY emp_actions AS


number_hired INT; -- visible only in this package

/* Fully define cursor specified in package. */


CURSOR desc_salary RETURN EmpRecTyp IS
SELECT empno, sal FROM emp ORDER BY sal DESC;

/* Fully define subprograms specified in package. */


FUNCTION hire_employee (
ename VARCHAR2,
job VARCHAR2,
mgr REAL,
sal REAL,

By Subhash Reddy Aedla Page 277 of 304


ORACLE

comm REAL,
deptno REAL) RETURN INT IS
new_empno INT;
BEGIN
SELECT empno_seq.NEXTVAL INTO new_empno FROM dual;
INSERT INTO emp VALUES (new_empno, ename, job,
mgr, SYSDATE, sal, comm, deptno);
number_hired := number_hired + 1;
RETURN new_empno;
END hire_employee;

PROCEDURE fire_employee (emp_id INT) IS


BEGIN
DELETE FROM emp WHERE empno = emp_id;
END fire_employee;

/* Define local function, available only inside package. */


FUNCTION sal_ok (rank INT, salary REAL) RETURN BOOLEAN IS
min_sal REAL;
max_sal REAL;
BEGIN
SELECT losal, hisal INTO min_sal, max_sal FROM salgrade
WHERE grade = rank;
RETURN (salary >= min_sal) AND (salary <= max_sal);
END sal_ok;

PROCEDURE raise_salary (emp_id INT, grade INT, amount REAL) IS


salary REAL;
BEGIN
SELECT sal INTO salary FROM emp WHERE empno = emp_id;
IF sal_ok(grade, salary + amount) THEN
UPDATE emp SET sal = sal + amount WHERE empno = emp_id;
ELSE
RAISE invalid_salary;
END IF;
END raise_salary;

FUNCTION nth_highest_salary (n INT) RETURN EmpRecTyp IS

By Subhash Reddy Aedla Page 278 of 304


ORACLE

emp_rec EmpRecTyp;
BEGIN
OPEN desc_salary;
FOR i IN 1..n LOOP
FETCH desc_salary INTO emp_rec;
END LOOP;
CLOSE desc_salary;
RETURN emp_rec;
END nth_highest_salary;

BEGIN -- initialization part starts here


INSERT INTO emp_audit VALUES (SYSDATE, USER, 'EMP_ACTIONS');
number_hired := 0;
END emp_actions;
/
Remember, the initialization part of a package is run just once, the first time you
reference the package. In the last example, only one row is inserted into the database
table emp_audit, and the variable number_hired is initialized only once.
Every time the procedure hire_employee is called, the variable number_hired is updated.
However, the count kept by number_hired is session specific. That is, the count reflects
the number of new employees processed by one user, not the number processed by all
users.
The following example is a package that handles typical bank transactions. Assume that
debit and credit transactions are entered after business hours through automatic teller
machines, then applied to accounts the next morning.
CREATE PACKAGE bank_transactions AS
/* Declare externally visible constant. */
minimum_balance CONSTANT REAL := 100.00;
/* Declare externally callable procedures. */
PROCEDURE apply_transactions;
PROCEDURE enter_transaction (
acct INT,
kind CHAR,
amount REAL);
END bank_transactions;
/

By Subhash Reddy Aedla Page 279 of 304


ORACLE

CREATE PACKAGE BODY bank_transactions AS


/* Declare global variable to hold transaction status. */
new_status VARCHAR2(70) := 'Unknown';

/* Use forward declarations because apply_transactions


calls credit_account and debit_account, which are not
yet declared when the calls are made. */
PROCEDURE credit_account (acct INT, credit REAL);
PROCEDURE debit_account (acct INT, debit REAL);

/* Fully define procedures specified in package. */


PROCEDURE apply_transactions IS
/* Apply pending transactions in transactions table
to accounts table. Use cursor to fetch rows. */
CURSOR trans_cursor IS
SELECT acct_id, kind, amount FROM transactions
WHERE status = 'Pending'
ORDER BY time_tag
FOR UPDATE OF status; -- to lock rows
BEGIN
FOR trans IN trans_cursor LOOP
IF trans.kind = 'D' THEN
debit_account(trans.acct_id, trans.amount);
ELSIF trans.kind = 'C' THEN
credit_account(trans.acct_id, trans.amount);
ELSE
new_status := 'Rejected';
END IF;
UPDATE transactions SET status = new_status
WHERE CURRENT OF trans_cursor;
END LOOP;
END apply_transactions;

PROCEDURE enter_transaction (
/* Add a transaction to transactions table. */
acct INT,
kind CHAR,
amount REAL) IS

By Subhash Reddy Aedla Page 280 of 304


ORACLE

BEGIN
INSERT INTO transactions
VALUES (acct, kind, amount, 'Pending', SYSDATE);
END enter_transaction;

/* Define local procedures, available only in package. */


PROCEDURE do_journal_entry (
/* Record transaction in journal. */
acct INT,
kind CHAR,
new_bal REAL) IS
BEGIN
INSERT INTO journal
VALUES (acct, kind, new_bal, sysdate);
IF kind = 'D' THEN
new_status := 'Debit applied';
ELSE
new_status := 'Credit applied';
END IF;
END do_journal_entry;

PROCEDURE credit_account (acct INT, credit REAL) IS


/* Credit account unless account number is bad. */
old_balance REAL;
new_balance REAL;
BEGIN
SELECT balance INTO old_balance FROM accounts
WHERE acct_id = acct
FOR UPDATE OF balance; -- to lock the row
new_balance := old_balance + credit;
UPDATE accounts SET balance = new_balance
WHERE acct_id = acct;
do_journal_entry(acct, 'C', new_balance);
EXCEPTION
WHEN NO_DATA_FOUND THEN
new_status := 'Bad account number';
WHEN OTHERS THEN
new_status := SUBSTR(SQLERRM,1,70);

By Subhash Reddy Aedla Page 281 of 304


ORACLE

END credit_account;

PROCEDURE debit_account (acct INT, debit REAL) IS


/* Debit account unless account number is bad or
account has insufficient funds. */
old_balance REAL;
new_balance REAL;
insufficient_funds EXCEPTION;
BEGIN
SELECT balance INTO old_balance FROM accounts
WHERE acct_id = acct
FOR UPDATE OF balance; -- to lock the row
new_balance := old_balance - debit;
IF new_balance >= minimum_balance THEN
UPDATE accounts SET balance = new_balance
WHERE acct_id = acct;
do_journal_entry(acct, 'D', new_balance);
ELSE
RAISE insufficient_funds;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
new_status := 'Bad account number';
WHEN insufficient_funds THEN
new_status := 'Insufficient funds';
WHEN OTHERS THEN
new_status := SUBSTR(SQLERRM,1,70);
END debit_account;
END bank_transactions;
/
In this package, the initialization part is not used.
Private Versus Public Items in Packages
In the package emp_actions, the package body declares a variable named number_hired,
which is initialized to zero. Items declared in the body are restricted to use within the
package. PL/SQL code outside the package cannot reference the variable number_hired.
Such items are called private.

By Subhash Reddy Aedla Page 282 of 304


ORACLE

Items declared in the spec of emp_actions, such as the exception invalid_salary, are visible
outside the package. Any PL/SQL code can reference the exception invalid_salary. Such
items are called public.
To maintain items throughout a session or across transactions, place them in the
declarative part of the package body. For example, the value of number_hired is kept
between calls to hire_employee within the same session. The value is lost when the
session ends.
To make the items public, place them in the package spec. For example, the constant
minimum_balance declared in the spec of the package bank_transactions is available for
general use.
Overloading Packaged Subprograms
PL/SQL allows two or more packaged subprograms to have the same name. This option
is useful when you want a subprogram to accept similar sets of parameters that have
different datatypes. For example, the following package defines two procedures named
journalize:
CREATE PACKAGE journal_entries AS
...
PROCEDURE journalize (amount REAL, trans_date VARCHAR2);
PROCEDURE journalize (amount REAL, trans_date INT);
END journal_entries;
/
CREATE PACKAGE BODY journal_entries AS
...
PROCEDURE journalize (amount REAL, trans_date VARCHAR2) IS
BEGIN
INSERT INTO journal
VALUES (amount, TO_DATE(trans_date, 'DD-MON-YYYY'));
END journalize;

PROCEDURE journalize (amount REAL, trans_date INT) IS


BEGIN
INSERT INTO journal
VALUES (amount, TO_DATE(trans_date, 'J'));
END journalize;
END journal_entries;
/

By Subhash Reddy Aedla Page 283 of 304


ORACLE

The first procedure accepts trans_date as a character string, while the second procedure
accepts it as a number (the Julian day). Each procedure handles the data appropriately.
For the rules that apply to overloaded subprograms, see "Overloading Subprogram
Names".
How Package STANDARD Defines the PL/SQL Environment
A package named STANDARD defines the PL/SQL environment. The package spec globally
declares types, exceptions, and subprograms, which are available automatically to
PL/SQL programs. For example, package STANDARD declares function ABS, which returns
the absolute value of its argument, as follows:
FUNCTION ABS (n NUMBER) RETURN NUMBER;
The contents of package STANDARD are directly visible to applications. You do not need to
qualify references to its contents by prefixing the package name. For example, you
might call ABS from a database trigger, stored subprogram, Oracle tool, or 3GL
application, as follows:
abs_diff := ABS(x - y);

If you declare your own version of ABS, your local declaration overrides the global
declaration. You can still call the built-in function by specifying its full name:
abs_diff := STANDARD.ABS(x - y);
Most built-in functions are overloaded. For example, package STANDARD contains the
following declarations:
FUNCTION TO_CHAR (right DATE) RETURN VARCHAR2;
FUNCTION TO_CHAR (left NUMBER) RETURN VARCHAR2;
FUNCTION TO_CHAR (left DATE, right VARCHAR2) RETURN VARCHAR2;
FUNCTION TO_CHAR (left NUMBER, right VARCHAR2) RETURN VARCHAR2;
PL/SQL resolves a call to TO_CHAR by matching the number and datatypes of the formal
and actual parameters.

Handling PL/SQL Errors


Overview of PL/SQL Runtime Error Handling
In PL/SQL, an error condition is called an exception. Exceptions can be internally defined
(by the runtime system) or user defined. Examples of internally defined exceptions
include division by zero and out of memory. Some common internal exceptions have

By Subhash Reddy Aedla Page 284 of 304


ORACLE

predefined names, such as ZERO_DIVIDE and STORAGE_ERROR. The other internal exceptions
can be given names.
You can define exceptions of your own in the declarative part of any PL/SQL block,
subprogram, or package. For example, you might define an exception named
insufficient_funds to flag overdrawn bank accounts. Unlike internal exceptions, user-
defined exceptions must be given names.
When an error occurs, an exception is raised. That is, normal execution stops and
control transfers to the exception-handling part of your PL/SQL block or subprogram.
Internal exceptions are raised implicitly (automatically) by the run-time system. User-
defined exceptions must be raised explicitly by RAISE statements, which can also raise
predefined exceptions.
To handle raised exceptions, you write separate routines called exception handlers.
After an exception handler runs, the current block stops executing and the enclosing
block resumes with the next statement. If there is no enclosing block, control returns to
the host environment.
The following example calculates a price-to-earnings ratio for a company. If the
company has zero earnings, the division operation raises the predefined exception
ZERO_DIVIDE, the execution of the block is interrupted, and control is transferred to the
exception handlers. The optional OTHERS handler catches all exceptions that the block
does not name specifically.
SET SERVEROUTPUT ON;
DECLARE
stock_price NUMBER := 9.73;
net_earnings NUMBER := 0;
pe_ratio NUMBER;
BEGIN
-- Calculation might cause division-by-zero error.
pe_ratio := stock_price / net_earnings;
dbms_output.put_line('Price/earnings ratio = ' || pe_ratio);

EXCEPTION -- exception handlers begin

-- Only one of the WHEN blocks is executed.


WHEN ZERO_DIVIDE THEN -- handles 'division by zero' error
dbms_output.put_line('Company must have had zero earnings.');
pe_ratio := null;

By Subhash Reddy Aedla Page 285 of 304


ORACLE

WHEN OTHERS THEN -- handles all other errors


dbms_output.put_line('Some other kind of error occurred.');
pe_ratio := null;

END; -- exception handlers and block end here


/
The last example illustrates exception handling. With some better error checking, we
could have avoided the exception entirely, by substituting a null for the answer if the
denominator was zero:
DECLARE
stock_price NUMBER := 9.73;
net_earnings NUMBER := 0;
pe_ratio NUMBER;
BEGIN
pe_ratio :=
case net_earnings
when 0 then null
else stock_price / net_earnings
end;
END;
/
Guidelines for Avoiding and Handling PL/SQL Errors and Exceptions
Because reliability is crucial for database programs, use both error checking and
exception handling to ensure your program can handle all possibilities:
 Add exception handlers whenever there is any possibility of an error occurring.
Errors are especially likely during arithmetic calculations, string manipulation,
and database operations. Errors could also occur at other times, for example if a
hardware failure with disk storage or memory causes a problem that has nothing
to do with your code; but your code still needs to take corrective action.
 Add error-checking code whenever you can predict that an error might occur if
your code gets bad input data. Expect that at some time, your code will be
passed incorrect or null parameters, that your queries will return no rows or
more rows than you expect.
 Make your programs robust enough to work even if the database is not in the
state you expect. For example, perhaps a table you query will have columns
added or deleted, or their types changed. You can avoid such problems by

By Subhash Reddy Aedla Page 286 of 304


ORACLE

declaring individual variables with %TYPE qualifiers, and declaring records to hold
query results with %ROWTYPE qualifiers.
 Handle named exceptions whenever possible, instead of using WHEN OTHERS in
exception handlers. Learn the names and causes of the predefined exceptions. If
your database operations might cause particular ORA- errors, associate names
with these errors so you can write handlers for them. (You will learn how to do
that later in this chapter.)
 Test your code with different combinations of bad data to see what potential
errors arise.
 Write out debugging information in your exception handlers. You might store
such information in a separate table. If so, do it by making a call to a procedure
declared with the PRAGMA AUTONOMOUS_TRANSACTION, so that you can commit
your debugging information, even if you roll back the work that the main
procedure was doing.
 Carefully consider whether each exception handler should commit the
transaction, roll it back, or let it continue. Remember, no matter how severe the
error is, you want to leave the database in a consistent state and avoid storing
any bad data.
Advantages of PL/SQL Exceptions
Using exceptions for error handling has several advantages.
With exceptions, you can reliably handle potential errors from many statements with a
single exception handler:
BEGIN
SELECT ...
SELECT ...
procedure_that_performs_select();
...
EXCEPTION
WHEN NO_DATA_FOUND THEN -- catches all 'no data found' errors

Instead of checking for an error at every point it might occur, just add an exception
handler to your PL/SQL block. If the exception is ever raised in that block (or any sub-
block), you can be sure it will be handled.

By Subhash Reddy Aedla Page 287 of 304


ORACLE

Sometimes the error is not immediately obvious, and could not be detected until later
when you perform calculations using bad data. Again, a single exception handler can
trap all division-by-zero errors, bad array subscripts, and so on.
If you need to check for errors at a specific spot, you can enclose a single statement or a
group of statements inside its own BEGIN-END block with its own exception handler.
You can make the checking as general or as precise as you like.
Isolating error-handling routines makes the rest of the program easier to read and
understand.
Summary of Predefined PL/SQL Exceptions
An internal exception is raised automatically if your PL/SQL program violates an Oracle
rule or exceeds a system-dependent limit. PL/SQL predefines some common Oracle
errors as exceptions. For example, PL/SQL raises the predefined exception
NO_DATA_FOUND if a SELECT INTO statement returns no rows.

You can use the pragma EXCEPTION_INIT to associate exception names with other Oracle
error codes that you can anticipate. To handle unexpected Oracle errors, you can use
the OTHERS handler. Within this handler, you can call the functions SQLCODE and SQLERRM
to return the Oracle error code and message text. Once you know the error code, you
can use it with pragma EXCEPTION_INIT and write a handler specifically for that error.
PL/SQL declares predefined exceptions globally in package STANDARD. You need not
declare them yourself. You can write handlers for predefined exceptions using the
names in the following list:

Exception Oracle Error SQLCODE Value

ACCESS_INTO_NULL ORA-06530 -6530

CASE_NOT_FOUND ORA-06592 -6592

COLLECTION_IS_NULL ORA-06531 -6531

CURSOR_ALREADY_OPEN ORA-06511 -6511

DUP_VAL_ON_INDEX ORA-00001 -1

INVALID_CURSOR ORA-01001 -1001

INVALID_NUMBER ORA-01722 -1722

LOGIN_DENIED ORA-01017 -1017

By Subhash Reddy Aedla Page 288 of 304


ORACLE

Exception Oracle Error SQLCODE Value

NO_DATA_FOUND ORA-01403 +100

NOT_LOGGED_ON ORA-01012 -1012

PROGRAM_ERROR ORA-06501 -6501

ROWTYPE_MISMATCH ORA-06504 -6504

SELF_IS_NULL ORA-30625 -30625

STORAGE_ERROR ORA-06500 -6500

SUBSCRIPT_BEYOND_COUNT ORA-06533 -6533

SUBSCRIPT_OUTSIDE_LIMIT ORA-06532 -6532

SYS_INVALID_ROWID ORA-01410 -1410

TIMEOUT_ON_RESOURCE ORA-00051 -51

TOO_MANY_ROWS ORA-01422 -1422

VALUE_ERROR ORA-06502 -6502

ZERO_DIVIDE ORA-01476 -1476

Brief descriptions of the predefined exceptions follow:

Exception Raised when ...

ACCESS_INTO_NULL A program attempts to assign values to the attributes of an


uninitialized object.

CASE_NOT_FOUND None of the choices in the WHEN clauses of a CASE statement is


selected, and there is no ELSE clause.

COLLECTION_IS_NULL A program attempts to apply collection methods other than


EXISTS to an uninitialized nested table or varray, or the program
attempts to assign values to the elements of an uninitialized
nested table or varray.

CURSOR_ALREADY_OPEN A program attempts to open an already open cursor. A cursor

By Subhash Reddy Aedla Page 289 of 304


ORACLE

Exception Raised when ...


must be closed before it can be reopened. A cursor FOR loop
automatically opens the cursor to which it refers, so your
program cannot open that cursor inside the loop.

DUP_VAL_ON_INDEX A program attempts to store duplicate values in a database


column that is constrained by a unique index.

INVALID_CURSOR A program attempts a cursor operation that is not allowed,


such as closing an unopened cursor.

INVALID_NUMBER In a SQL statement, the conversion of a character string into a


number fails because the string does not represent a valid
number. (In procedural statements, VALUE_ERROR is raised.)
This exception is also raised when the LIMIT-clause expression
in a bulk FETCH statement does not evaluate to a positive
number.

LOGIN_DENIED A program attempts to log on to Oracle with an invalid


username or password.

NO_DATA_FOUND A SELECT INTO statement returns no rows, or your program


references a deleted element in a nested table or an
uninitialized element in an index-by table.
Because this exception is used internally by some SQL
functions to signal that they are finished, you should not rely
on this exception being propagated if you raise it within a
function that is called as part of a query.

NOT_LOGGED_ON A program issues a database call without being connected to


Oracle.

PROGRAM_ERROR PL/SQL has an internal problem.

ROWTYPE_MISMATCH The host cursor variable and PL/SQL cursor variable involved in
an assignment have incompatible return types. For example,
when an open host cursor variable is passed to a stored
subprogram, the return types of the actual and formal
parameters must be compatible.

By Subhash Reddy Aedla Page 290 of 304


ORACLE

Exception Raised when ...

SELF_IS_NULL A program attempts to call a MEMBER method, but the instance


of the object type has not been initialized. The built-in
parameter SELF points to the object, and is always the first
parameter passed to a MEMBER method.

STORAGE_ERROR PL/SQL runs out of memory or memory has been corrupted.

SUBSCRIPT_BEYOND_COUNT A program references a nested table or varray element using


an index number larger than the number of elements in the
collection.

SUBSCRIPT_OUTSIDE_LIMIT A program references a nested table or varray element using


an index number (-1 for example) that is outside the legal
range.

SYS_INVALID_ROWID The conversion of a character string into a universal rowid fails


because the character string does not represent a valid rowid.

TIMEOUT_ON_RESOURCE A time-out occurs while Oracle is waiting for a resource.

TOO_MANY_ROWS A SELECT INTO statement returns more than one row.

VALUE_ERROR An arithmetic, conversion, truncation, or size-constraint error


occurs. For example, when your program selects a column
value into a character variable, if the value is longer than the
declared length of the variable, PL/SQL aborts the assignment
and raises VALUE_ERROR. In procedural statements, VALUE_ERROR
is raised if the conversion of a character string into a number
fails. (In SQL statements, INVALID_NUMBER is raised.)

ZERO_DIVIDE A program attempts to divide a number by zero.

Defining Your Own PL/SQL Exceptions


PL/SQL lets you define exceptions of your own. Unlike predefined exceptions, user-
defined exceptions must be declared and must be raised explicitly by RAISE statements.

By Subhash Reddy Aedla Page 291 of 304


ORACLE

Declaring PL/SQL Exceptions


Exceptions can be declared only in the declarative part of a PL/SQL block, subprogram,
or package. You declare an exception by introducing its name, followed by the keyword
EXCEPTION. In the following example, you declare an exception named past_due:

DECLARE
past_due EXCEPTION;

Exception and variable declarations are similar. But remember, an exception is an error
condition, not a data item. Unlike variables, exceptions cannot appear in assignment
statements or SQL statements. However, the same scope rules apply to variables and
exceptions.
Scope Rules for PL/SQL Exceptions
You cannot declare an exception twice in the same block. You can, however, declare the
same exception in two different blocks.
Exceptions declared in a block are considered local to that block and global to all its sub-
blocks. Because a block can reference only local or global exceptions, enclosing blocks
cannot reference exceptions declared in a sub-block.
If you redeclare a global exception in a sub-block, the local declaration prevails. The sub-
block cannot reference the global exception, unless the exception is declared in a
labeled block and you qualify its name with the block label:
block_label.exception_name

The following example illustrates the scope rules:


DECLARE
past_due EXCEPTION;
acct_num NUMBER;
BEGIN
DECLARE ---------- sub-block begins
past_due EXCEPTION; -- this declaration prevails
acct_num NUMBER;
due_date DATE := SYSDATE - 1;
todays_date DATE := SYSDATE;
BEGIN
IF due_date < todays_date THEN

By Subhash Reddy Aedla Page 292 of 304


ORACLE

RAISE past_due; -- this is not handled


END IF;
END; ------------- sub-block ends
EXCEPTION
WHEN past_due THEN -- does not handle RAISEd exception
dbms_output.put_line('Handling PAST_DUE exception.');
WHEN OTHERS THEN
dbms_output.put_line('Could not recognize PAST_DUE_EXCEPTION in this scope.');
END;
/
The enclosing block does not handle the raised exception because the declaration of
past_due in the sub-block prevails. Though they share the same name, the two past_due
exceptions are different, just as the two acct_num variables share the same name but are
different variables. Thus, the RAISE statement and the WHEN clause refer to different
exceptions. To have the enclosing block handle the raised exception, you must remove
its declaration from the sub-block or define an OTHERS handler.
Associating a PL/SQL Exception with a Number: Pragma EXCEPTION_INIT
To handle error conditions (typically ORA- messages) that have no predefined name, you
must use the OTHERS handler or the pragma EXCEPTION_INIT. A pragma is a compiler
directive that is processed at compile time, not at run time.
In PL/SQL, the pragma EXCEPTION_INIT tells the compiler to associate an exception name
with an Oracle error number. That lets you refer to any internal exception by name and
to write a specific handler for it. When you see an error stack, or sequence of error
messages, the one on top is the one that you can trap and handle.
You code the pragma EXCEPTION_INIT in the declarative part of a PL/SQL block,
subprogram, or package using the syntax
PRAGMA EXCEPTION_INIT(exception_name, -Oracle_error_number);

where exception_name is the name of a previously declared exception and the number is a
negative value corresponding to an ORA- error number. The pragma must appear
somewhere after the exception declaration in the same declarative section, as shown in
the following example:
DECLARE
deadlock_detected EXCEPTION;
PRAGMA EXCEPTION_INIT(deadlock_detected, -60);

By Subhash Reddy Aedla Page 293 of 304


ORACLE

BEGIN
null; -- Some operation that causes an ORA-00060 error
EXCEPTION
WHEN deadlock_detected THEN
null; -- handle the error
END;
/
Defining Your Own Error Messages: Procedure RAISE_APPLICATION_ERROR
The procedure RAISE_APPLICATION_ERROR lets you issue user-defined ORA- error messages
from stored subprograms. That way, you can report errors to your application and avoid
returning unhandled exceptions.
To call RAISE_APPLICATION_ERROR, use the syntax
raise_application_error(error_number, message[, {TRUE | FALSE}]);

where error_number is a negative integer in the range -20000 .. -20999 and message is a
character string up to 2048 bytes long. If the optional third parameter is TRUE, the error
is placed on the stack of previous errors. If the parameter is FALSE (the default), the error
replaces all previous errors. RAISE_APPLICATION_ERROR is part of package DBMS_STANDARD,
and as with package STANDARD, you do not need to qualify references to it.
An application can call raise_application_error only from an executing stored subprogram
(or method). When called, raise_application_error ends the subprogram and returns a user-
defined error number and message to the application. The error number and message
can be trapped like any Oracle error.
In the following example, you call raise_application_error if an error condition of your
choosing happens (in this case, if the current schema owns less than 1000 tables):
DECLARE
num_tables NUMBER;
BEGIN
SELECT COUNT(*) INTO num_tables FROM USER_TABLES;
IF num_tables < 1000 THEN
/* Issue your own error code (ORA-20101) with your own error message. */
raise_application_error(-20101, 'Expecting at least 1000 tables');
ELSE
NULL; -- Do the rest of the processing (for the non-error case).
END IF;

By Subhash Reddy Aedla Page 294 of 304


ORACLE

END;
/
The calling application gets a PL/SQL exception, which it can process using the error-
reporting functions SQLCODE and SQLERRM in an OTHERS handler. Also, it can use the
pragma EXCEPTION_INIT to map specific error numbers returned by raise_application_error to
exceptions of its own, as the following Pro*C example shows:
EXEC SQL EXECUTE
/* Execute embedded PL/SQL block using host
variables my_emp_id and my_amount, which were
assigned values in the host environment. */
DECLARE
null_salary EXCEPTION;
/* Map error number returned by raise_application_error
to user-defined exception. */
PRAGMA EXCEPTION_INIT(null_salary, -20101);
BEGIN
raise_salary(:my_emp_id, :my_amount);
EXCEPTION
WHEN null_salary THEN
INSERT INTO emp_audit VALUES (:my_emp_id, ...);
END;
END-EXEC;

This technique allows the calling application to handle error conditions in specific
exception handlers.
Redeclaring Predefined Exceptions
Remember, PL/SQL declares predefined exceptions globally in package STANDARD, so you
need not declare them yourself. Redeclaring predefined exceptions is error prone
because your local declaration overrides the global declaration. For example, if you
declare an exception named invalid_number and then PL/SQL raises the predefined
exception INVALID_NUMBER internally, a handler written for INVALID_NUMBER will not catch
the internal exception. In such cases, you must use dot notation to specify the
predefined exception, as follows:
EXCEPTION
WHEN invalid_number OR STANDARD.INVALID_NUMBER THEN

By Subhash Reddy Aedla Page 295 of 304


ORACLE

-- handle the error


END;
How PL/SQL Exceptions Are Raised
Internal exceptions are raised implicitly by the run-time system, as are user-defined
exceptions that you have associated with an Oracle error number using EXCEPTION_INIT.
However, other user-defined exceptions must be raised explicitly by RAISE statements.
Raising Exceptions with the RAISE Statement
PL/SQL blocks and subprograms should raise an exception only when an error makes it
undesirable or impossible to finish processing. You can place RAISE statements for a
given exception anywhere within the scope of that exception. In the following example,
you alert your PL/SQL block to a user-defined exception named out_of_stock:
DECLARE
out_of_stock EXCEPTION;
number_on_hand NUMBER := 0;
BEGIN
IF number_on_hand < 1 THEN
RAISE out_of_stock; -- raise an exception that we defined
END IF;
EXCEPTION
WHEN out_of_stock THEN
-- handle the error
dbms_output.put_line('Encountered out-of-stock error.');
END;
/
You can also raise a predefined exception explicitly. That way, an exception handler
written for the predefined exception can process other errors, as the following example
shows:
DECLARE
acct_type INTEGER := 7;
BEGIN
IF acct_type NOT IN (1, 2, 3) THEN
RAISE INVALID_NUMBER; -- raise predefined exception
END IF;
EXCEPTION
WHEN INVALID_NUMBER THEN
dbms_output.put_line('Handling invalid input by rolling back.');

By Subhash Reddy Aedla Page 296 of 304


ORACLE

ROLLBACK;
END;
/
How PL/SQL Exceptions Propagate
When an exception is raised, if PL/SQL cannot find a handler for it in the current block or
subprogram, the exception propagates. That is, the exception reproduces itself in
successive enclosing blocks until a handler is found or there are no more blocks to
search. If no handler is found, PL/SQL returns an unhandled exception error to the host
environment.
Exceptions cannot propagate across remote procedure calls done through database
links. A PL/SQL block cannot catch an exception raised by a remote subprogram. For a
workaround, see "Defining Your Own Error Messages: Procedure
RAISE_APPLICATION_ERROR".
Figure 10-1, Figure 10-2, and Figure 10-3 illustrate the basic propagation rules.
Figure - Propagation Rules: Example 1

Figure - Propagation Rules: Example 2

By Subhash Reddy Aedla Page 297 of 304


ORACLE

Figure - Propagation Rules: Example 3

An exception can propagate beyond its scope, that is, beyond the block in which it was
declared. Consider the following example:
BEGIN
DECLARE ---------- sub-block begins
past_due EXCEPTION;

By Subhash Reddy Aedla Page 298 of 304


ORACLE

due_date DATE := trunc(SYSDATE) - 1;


todays_date DATE := trunc(SYSDATE);
BEGIN
IF due_date < todays_date THEN
RAISE past_due;
END IF;
END; ------------- sub-block ends
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END;
/
Because the block that declares the exception past_due has no handler for it, the
exception propagates to the enclosing block. But the enclosing block cannot reference
the name PAST_DUE, because the scope where it was declared no longer exists. Once the
exception name is lost, only an OTHERS handler can catch the exception. If there is no
handler for a user-defined exception, the calling application gets this error:
ORA-06510: PL/SQL: unhandled user-defined exception
Reraising a PL/SQL Exception
Sometimes, you want to reraise an exception, that is, handle it locally, then pass it to an
enclosing block. For example, you might want to roll back a transaction in the current
block, then log the error in an enclosing block.
To reraise an exception, use a RAISE statement without an exception name, which is
allowed only in an exception handler:
DECLARE
salary_too_high EXCEPTION;
current_salary NUMBER := 20000;
max_salary NUMBER := 10000;
erroneous_salary NUMBER;
BEGIN
BEGIN ---------- sub-block begins
IF current_salary > max_salary THEN
RAISE salary_too_high; -- raise the exception
END IF;
EXCEPTION
WHEN salary_too_high THEN

By Subhash Reddy Aedla Page 299 of 304


ORACLE

-- first step in handling the error


dbms_output.put_line('Salary ' || erroneous_salary ||
' is out of range.');
dbms_output.put_line('Maximum salary is ' || max_salary || '.');
RAISE; -- reraise the current exception
END; ------------ sub-block ends
EXCEPTION
WHEN salary_too_high THEN
-- handle the error more thoroughly
erroneous_salary := current_salary;
current_salary := max_salary;
dbms_output.put_line('Revising salary from ' || erroneous_salary ||
'to ' || current_salary || '.');
END;
/
Handling Raised PL/SQL Exceptions
When an exception is raised, normal execution of your PL/SQL block or subprogram
stops and control transfers to its exception-handling part, which is formatted as follows:
EXCEPTION
WHEN exception_name1 THEN -- handler
sequence_of_statements1
WHEN exception_name2 THEN -- another handler
sequence_of_statements2
...
WHEN OTHERS THEN -- optional handler
sequence_of_statements3
END;

To catch raised exceptions, you write exception handlers. Each handler consists of a
WHEN clause, which specifies an exception, followed by a sequence of statements to be
executed when that exception is raised. These statements complete execution of the
block or subprogram; control does not return to where the exception was raised. In
other words, you cannot resume processing where you left off.
The optional OTHERS exception handler, which is always the last handler in a block or
subprogram, acts as the handler for all exceptions not named specifically. Thus, a block
or subprogram can have only one OTHERS handler.

By Subhash Reddy Aedla Page 300 of 304


ORACLE

As the following example shows, use of the OTHERS handler guarantees that no exception
will go unhandled:
EXCEPTION
WHEN ... THEN
-- handle the error
WHEN ... THEN
-- handle the error
WHEN OTHERS THEN
-- handle all other errors
END;

If you want two or more exceptions to execute the same sequence of statements, list
the exception names in the WHEN clause, separating them by the keyword OR, as follows:
EXCEPTION
WHEN over_limit OR under_limit OR VALUE_ERROR THEN
-- handle the error

If any of the exceptions in the list is raised, the associated sequence of statements is
executed. The keyword OTHERS cannot appear in the list of exception names; it must
appear by itself. You can have any number of exception handlers, and each handler can
associate a list of exceptions with a sequence of statements. However, an exception
name can appear only once in the exception-handling part of a PL/SQL block or
subprogram.
The usual scoping rules for PL/SQL variables apply, so you can reference local and global
variables in an exception handler. However, when an exception is raised inside a cursor
FOR loop, the cursor is closed implicitly before the handler is invoked. Therefore, the
values of explicit cursor attributes are not available in the handler.
Handling Exceptions Raised in Declarations
Exceptions can be raised in declarations by faulty initialization expressions. For example,
the following declaration raises an exception because the constant credit_limit cannot
store numbers larger than 999:
DECLARE
credit_limit CONSTANT NUMBER(3) := 5000; -- raises an exception
BEGIN
NULL;

By Subhash Reddy Aedla Page 301 of 304


ORACLE

EXCEPTION
WHEN OTHERS THEN
-- Cannot catch the exception. This handler is never called.
dbms_output.put_line('Can''t handle an exception in a declaration.');
END;
/
Handlers in the current block cannot catch the raised exception because an exception
raised in a declaration propagates immediately to the enclosing block.
Handling Exceptions Raised in Handlers
When an exception occurs within an exception handler, that same handler cannot catch
the exception. An exception raised inside a handler propagates immediately to the
enclosing block, which is searched to find a handler for this new exception. From there
on, the exception propagates normally. For example:
EXCEPTION
WHEN INVALID_NUMBER THEN
INSERT INTO ... -- might raise DUP_VAL_ON_INDEX
WHEN DUP_VAL_ON_INDEX THEN ... -- cannot catch the exception
END;
Branching to or from an Exception Handler
A GOTO statement can branch from an exception handler into an enclosing block.
A GOTO statement cannot branch into an exception handler, or from an exception
handler into the current block.
Retrieving the Error Code and Error Message: SQLCODE and SQLERRM
In an exception handler, you can use the built-in functions SQLCODE and SQLERRM to find
out which error occurred and to get the associated error message. For internal
exceptions, SQLCODE returns the number of the Oracle error. The number that SQLCODE
returns is negative unless the Oracle error is no data found, in which case SQLCODE
returns +100. SQLERRM returns the corresponding error message. The message begins
with the Oracle error code.
For user-defined exceptions, SQLCODE returns +1 and SQLERRM returns the message: User-
Defined Exception.

unless you used the pragma EXCEPTION_INIT to associate the exception name with an
Oracle error number, in which case SQLCODE returns that error number and SQLERRM
returns the corresponding error message. The maximum length of an Oracle error

By Subhash Reddy Aedla Page 302 of 304


ORACLE

message is 512 characters including the error code, nested messages, and message
inserts such as table and column names.
If no exception has been raised, SQLCODE returns zero and SQLERRM returns the message:
ORA-0000: normal, successful completion.

You can pass an error number to SQLERRM, in which case SQLERRM returns the message
associated with that error number. Make sure you pass negative error numbers to
SQLERRM.

Passing a positive number to SQLERRM always returns the message user-defined


exception unless you pass +100, in which case SQLERRM returns the message no data
found. Passing a zero to SQLERRM always returns the message normal, successful
completion.
You cannot use SQLCODE or SQLERRM directly in a SQL statement. Instead, you must assign
their values to local variables, then use the variables in the SQL statement, as shown in
the following example:
DECLARE
err_msg VARCHAR2(100);
BEGIN
/* Get a few Oracle error messages. */
FOR err_num IN 1..3 LOOP
err_msg := SUBSTR(SQLERRM(-err_num),1,100);
dbms_output.put_line('Error number = ' || err_num);
dbms_output.put_line('Error message = ' || err_msg);
END LOOP;
END;
/
The string function SUBSTR ensures that a VALUE_ERROR exception (for truncation) is not
raised when you assign the value of SQLERRM to err_msg. The functions SQLCODE and
SQLERRM are especially useful in the OTHERS exception handler because they tell you
which internal exception was raised.
Note: When using pragma RESTRICT_REFERENCES to assert the purity of a stored function,
you cannot specify the constraints WNPS and RNPS if the function calls SQLCODE or
SQLERRM.

Catching Unhandled Exceptions


Remember, if it cannot find a handler for a raised exception, PL/SQL returns an
unhandled exception error to the host environment, which determines the outcome.

By Subhash Reddy Aedla Page 303 of 304


ORACLE

For example, in the Oracle Precompilers environment, any database changes made by a
failed SQL statement or PL/SQL block are rolled back.
Unhandled exceptions can also affect subprograms. If you exit a subprogram
successfully, PL/SQL assigns values to OUT parameters. However, if you exit with an
unhandled exception, PL/SQL does not assign values to OUT parameters (unless they are
NOCOPY parameters). Also, if a stored subprogram fails with an unhandled exception,
PL/SQL does not roll back database work done by the subprogram.
You can avoid unhandled exceptions by coding an OTHERS handler at the topmost level of
every PL/SQL program.

By Subhash Reddy Aedla Page 304 of 304

Você também pode gostar