0% found this document useful (0 votes)
179 views125 pages

OracleDoc PDF

Uploaded by

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

OracleDoc PDF

Uploaded by

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

RDBMS using Oracle

RDBMS – Oracle
Let's before start working with Oracle first we have to look into a jargon of the concepts related to database
fundamentals. Following diagram maps that where is the oracle stands in our computer world. It is one of
the most widely used Relational Database Management System in the world.

DBMS: The Database Management System (DBMS) is a set of computer programs that controls the creation,
maintenance, and the use of a database. In order to manage data in database we need an efficient system
that organizes, manages and manipulates the database. Such software is called as a Database Management
System. Question rises here, what is data?
Data: The data is a collection of facts. The
word data is plural of word Datum which is
an item of factual information derived from
measurement or research. All human data
are managed under two distinct types i.e.
Characters (A, B, C, +, -, & etc.) or Numbers
(1, 2, 3, 0 etc.).
Database: The database is an organized
collection of information. It is a tool for
organizing, sorting, maintaining, calculating,
combining, and retrieving information.

If we have to collect data of many persons then it is


necessary to organized in a particular manner. The
same set of information about persons which is shown
unorganized in picture can be organized in a proper
order as a collection of structure and records.
A collection of structure and records is called as
database. Now what is a structure and what is a record?

© [email protected] RDBMS Oracle / Page 1 of 125


RDBMS using Oracle
Let's understand it in following diagram showing a managed form of data of persons.

The above diagram illustrates the organization in the reference of a database. This database manages data
of few persons in terms of Fields and records let's see what are these terminologies?
Field: The field is a name given to a group of similar data. It is a location where we collect information
related to same data. You can assume it as heading of that group. In other words fields are popularly called
as Column and Attribute also.
Record: The record is a collection of information about single entity. Such as "Ram Kumar, 102, Ashok Nagar,
2123456" is all about a person named Ram. So, we can say it is a collection of relative data. The Row & Tuple
are other names given to a record.
Structure: The structure is a collection of fields that organizes an order of data collection. It builds a
template or design in which data will be collected in a database.
Data Model: The structure of database is dependent on data models. A data model is collection of
conceptual tools that describe the data, data relationships, and consistency constraints. The diagram below
describes a list of various data models popular in DBMS world.

© [email protected] RDBMS Oracle / Page 2 of 125


RDBMS using Oracle
RDBMS: The RDBMS is based upon the relational model. It generates a set of relation schemes that allow
user to retrieve information without redundancy. It provides data integration and eliminates the difficulty in
accessing and manipulating data. It offers uniform security and privacy control. Data sharing can be
accomplished easily.
Origin: E. F. Codd introduced the term in his seminal paper "A Relational Model of Data for Large Shared
Data Banks", published in 1970. In this paper and later papers he defined what he meant by relational. One
well-known definition of what constitutes a relational database system is Codd's 12 rules. However, many of
the early implementations of the relational model did not conform to all of Codd's rules, so the term
gradually came to describe a broader class of database systems. At a minimum, these systems:
• presented the data to the user as relations (a presentation in tabular form, i.e. as a collection of
tables with each table consisting of a set of rows and columns, can satisfy this property)
• provided relational operators to manipulate the data in tabular form
The most popular definition of an RDBMS is a product that presents a view of data as a collection of rows
and columns, even if it is not based strictly upon relational theory.
Difference between DBMS and RDBMS
DBMS RDBMS
The concept of relationship is missing and if Based on the concept of relationships.
exists, it is very less.
Speed of operation is very slow. Speed of operation is very fast.
Hardware and software requirements are less. Hardware and software requirements are very
high.
Facilities and utilities offered are limited. Facilities and utilities offered are many.
Platform usually DOS. Platform used can be any. DOS, Windows, Unix
etc.
Uses concept of File. Uses concept of Table.
DBMS normally use a 3GL. RDBMS normally use a 4GL.
Example : dBASE, FOXBASE, CLIPPER, etc. Example : ORACLE, UNIFY, FOCUS, INTGRESS,
etc.
Relation: A relation is a data structure which consists of a heading and an unordered set of tuples which
share the same type. When Edgar F. Codd invented the relational model, he generalized the concept of
binary relation (mathematical relation) to n-ary relation. Relation is a fundamental concept in relational
model. A relation has zero or more tuples. A relation value is an instance of a relation. A relation variable is a
variable which has a relation value.
Entity Relationship Model:
The Entity-Relationship (E-R ) model is based on
Object based Logical Model. It consists of a set
of basic Objects called Entities and Relationships
among these Objects. Entity is an object that
exists and distinguishable from other objects.
An Entity may be a person, a book, or it may be
abstract that uniquely identifies it in a database
or table. Entity Set is a set of entities of the
same type. The set of persons studying in a class
can be defined as an entity set of students.
Relationship is an association between two or
more entities. E-R Data Model defines certain

© [email protected] RDBMS Oracle / Page 3 of 125


RDBMS using Oracle
constraints to which the data in the database must satisfy are called Mapping Cardinalities. The diagram
besides, describes ER Mapping Cardinalities.
Oracle
The Oracle Database is a relational database management system (RDBMS) produced and marketed by
Oracle Corporation. As of 2010, Oracle has been a major presence in database computing for many years.
Larry Ellison and his friends and former co-workers Bob Miner and Ed Oates started the consultancy
Software Development Laboratories (SDL) in 1977. SDL developed the original version of the Oracle
software. The name Oracle comes from the code name of a CIA-funded project Ellison had worked on while
previously employed by Ampex. Later on different releases were introduced but since version 5, Oracle's
RDBMS release numbering has used the following codes:
• Oracle5
• Oracle6
• Oracle7: 7.0.16—7.3.4
• Oracle8 Database: 8.0.3—8.0.6
• Oracle8i Database Release 1: 8.1.5.0—8.1.5.1
• Oracle8i Database Release 2: 8.1.6.0—8.1.6.3
• Oracle8i Database Release 3: 8.1.7.0—8.1.7.4
• Oracle9i Database Release 1: 9.0.1.0—9.0.1.5 (patchset as of December 2003)
• Oracle9i Database Release 2: 9.2.0.1—9.2.0.8 (patchset as of April 2007)
• Oracle Database 10g Release 1: 10.1.0.2—10.1.0.5 (patchset as of February 2006)
• Oracle Database 10g Release 2: 10.2.0.1—10.2.0.5 (patchset as of April 2010)
• Oracle Database 11g Release 1: 11.1.0.6—11.1.0.7 (patchset as of September 2008)
• Oracle Database 11g Release 2: 11.2.0.1 (released 2009-09-01)
Oracle Corporation claims to have provided:
• the first commercially-available SQL-based database (1979)
• the first database to support symmetric multiprocessing (SMP) (1983)
• the first distributed database (1986)
• the first database product tested to comply with the ANSI SQL standard (1993)
• the first 64-bit database (1995)
• the first database to incorporate a native JRE (1998)
• the first proprietary RDBMS to become available on Linux (1998)
• the first database to support XML (1999)
Oracle Database Architecture
A database is a collection of data treated as a unit. The purpose of a database is to store and retrieve related
information. A database server is the key to information management. In general, a server reliably manages
a large amount of data in a multiuser environment so that many users can concurrently access the same
data. A database server also prevents unauthorized access and provides efficient solutions for failure
recovery.
The database has physical structures and logical structures. Because the physical and logical structures are
separate, the physical storage of data can be managed without affecting access to logical storage structures.
Grid Architecture
Oracle Database is the first database designed for enterprise grid computing, the most flexible and cost-
effective way to manage information and applications. Enterprise grid computing creates large pools of
industry-standard, modular storage and servers. With this architecture, each new system can be rapidly

© [email protected] RDBMS Oracle / Page 4 of 125


RDBMS using Oracle
provisioned from the pool of components. There is no need to provide extra hardware to support peak
workloads, because capacity can be easily added or reallocated from the resource pools as needed.
Grid computing is an information technology (IT) architecture that produces more resilient and lower cost
enterprise information systems. With grid computing, groups of independent, modular hardware and
software components can be connected and rejoined on demand to meet the changing needs of businesses.
Application Architecture
The two most common database architectures are client/server and multitier. As internet computing
becomes more prevalent in computing environments, many database management systems are moving to a
multitier environment.
Client/Server Architecture: An Oracle database system can easily take advantage of distributed processing
by using its client/server architecture. In this architecture, the database system has two parts: a front-end or
a client, and a back-end or a server.
Multitier Architecture: A traditional multitier architecture has the following components: A client or initiator
process that starts an operation, and one or more application servers that perform parts of the operation.
An application server contains a large part of the application logic, provides access to the data for the client,
and performs some query processing, thus removing some of the load from the database server. The
application server can serve as an interface between clients and multiple database servers and can provide
an additional level of security. An end server or database server that stores most of the data used in the
operation. This architecture enables use of an application server to do the following:
• Validate the credentials of a client, such as a Web browser
• Connect to an Oracle Database server
• Perform the requested operation on behalf of the client
If proxy authentication is being used, then the identity of the client is maintained throughout all tiers of the
connection.
Physical and logical Architecture
Oracle database system—identified by an alphanumeric system identifier or SID—comprises at least one
instance of the application, along with data storage. An instance—identified persistently by an instantiation
number (or activation id: SYS.V_$DATABASE.ACTIVATION#)—comprises a set of operating-system processes
and memory structures that interact with the storage. Typical processes include PMON (the process
monitor) and SMON (the system monitor).
Users of the Oracle databases refer to the server-side memory-structure as the SGA (System Global Area).
The SGA typically holds cache information such as data-buffers, SQL commands, and user information. In
addition to storage, the database consists of online redo logs (or logs), which hold transactional history.
Processes can in turn archive the online redo logs into archive logs (offline redo logs), which provide the
basis (if necessary) for data recovery and for some forms of data replication.
If the Oracle database administrator has implemented Oracle RAC (Real Application Clusters), then multiple
instances, usually on different servers, attach to a central storage array. This scenario offers advantages such
as better performance, scalability and redundancy. However, support becomes more complex, and many
sites do not use RAC. In version 10g, grid computing introduced shared resources where an instance can use
(for example) CPU resources from another node (computer) in the grid. The Oracle DBMS can store and
execute stored procedures and functions within it. PL/SQL (Oracle Corporation's proprietary procedural
extension to SQL), or the object-oriented language Java can invoke such code objects and/or provide the
programming structures for writing them.

© [email protected] RDBMS Oracle / Page 5 of 125


RDBMS using Oracle
Storage
The Oracle RDBMS stores data logically in the form of tablespaces and physically in the form of data files.
Tablespaces can contain various types of memory segments, such as Data Segments, Index Segments, etc.
Segments in turn comprise one or more extents. Extents comprise groups of contiguous data blocks. Data
blocks forms the basic units of data storage.
Oracle database management tracks its computer data storage with the help of information stored in the
SYSTEM tablespace. The SYSTEM tablespace contains the data dictionary—and often (by default) indexes
and clusters. A data dictionary consists of a special collection of tables that contains information about all
user-objects in the database. Since version 8i, the Oracle RDBMS also supports "locally managed"
tablespaces which can store space management information in bitmaps in their own headers rather than in
the SYSTEM tablespace (as happens with the default "dictionary-managed" tablespaces).
DBA: A database administrator (DBA) is a person responsible for the design, implementation, maintenance
and repair of an organization's database. They are also known by the titles Database Coordinator or
Database Programmer, and are closely related to the Database Analyst, Database Modeler, Programmer
Analyst, and Systems Manager. The role includes the development and design of database strategies,
monitoring and improving database performance and capacity, and planning for future expansion
requirements. They may also plan, co-ordinate and implement security measures to safeguard the database.

Role of DBA Role of Enduser


Creating primary database storage structures. Connect to the database.
Modifying the structure of the database. Query the database.
Backing up and restoring the database. Generate printed output.
Transferring data between the database and Share data with or secure data from others.
external files.
Creating users and assign them their rights. Use non-expert methods to update database.
Maintain security of database and controlling Define applications from a user's point of view.
user access to database.
Database schema
Oracle database conventions refer to defined groups of object ownership (generally associated with a
"username") as schemas. Most Oracle database installations traditionally came with a default schema called
SCOTT. After the installation process has set up the sample tables, the user can log into the database with
the username scott and the password tiger. The name of the SCOTT schema originated with Bruce Scott, one
of the first employees at Oracle (then Software Development Laboratories), who had a cat named Tiger.
Oracle Corporation has de-emphasized the use of the SCOTT schema, as it uses few of the features of the
more recent releases of Oracle. Most recent examples supplied by Oracle Corporation reference the default
HR or OE schemas. Other default schemas include:
• SYS (essential core database structures and utilities)
• SYSTEM (additional core database structures and utilities, and privileged account)
• OUTLN (utilized to store metadata for stored outlines for stable query-optimizer execution plans.
• BI, IX, HR, OE, PM, and SH (expanded sample schemas containing more data and structures than the
older SCOTT schema).
Overview of Schemas and Common Schema Objects
A schema is a collection of database objects. A schema is owned by a database user and has the same name
as that user. Schema objects are the logical structures that directly refer to the database's data. There is no
relationship between a tablespace and a schema. Objects in the same schema can be in different
tablespaces, and a tablespace can hold objects from different schemas. Schema objects include structures

© [email protected] RDBMS Oracle / Page 6 of 125


RDBMS using Oracle
such as tables, views, and indexes. Some of the most common schema objects are defined in the sections
that follow.

• Tables
• Indexes
• Views
• Clusters
• Synonyms
Table
In relational databases and flat file databases, a table is a set of data elements (values) that are organized
using a model of vertical columns (which are identified by their name) and horizontal rows. A table has a
specified number of columns, but can have any number of rows. Each row is identified by the values
appearing in a particular column subset which has been identified as a candidate key.
Table is another term for relations; although there is the difference in that a table is usually a multi-set (bag)
of rows whereas a relation is a set and does not allow duplicates. Besides the actual data rows, tables
generally have associated with them some meta-information, such as constraints on the table or on the
values within particular columns. The data in a table does not have to be physically stored in the database.
Views are also relational tables, but their data are calculated at query time.
Tables are the basic unit of data storage in an Oracle database. Database tables hold all user-accessible data.
Each table has columns and rows. A table that has employee information, for example, can have a column
called employee_number, and each row in that column is an employee number.
Indexes
Indexes are optional structures associated with tables. You can create indexes to increase the performance
of data retrieval. Just as the index in this manual helps you quickly locate specific information, an Oracle
database index provides an access path to table data.
Views
Views are customized presentations of data in one or more tables or other views. A view can also be
considered a stored query. Views do not contain actual data. Rather, they derive their data from the tables
on which they are based, referred to as the base tables of the views. You can query, update, insert into, and
delete views as you can with tables, with some restrictions. If the view is updatable, then all operations
performed on the view actually affect the base tables of the view. Views can provide table security by
restricting access to a predetermined set of rows and columns of a table. They also hide data complexity and
store complex queries.
Clusters
Clusters are groups of one or more tables physically stored together because they share common columns
and are often used together. Because related rows are physically stored together, disk access time improves.
Like indexes, clusters do not affect application design. Whether a table is part of a cluster is transparent to
users and to applications. SQL statements access data stored in a clustered table in the same way that they
access data stored in a non-clustered table.
Synonyms
A synonym is an alias for any table, view, materialized view, sequence, operator, procedure, function,
package, Java class schema object, user-defined object type, or another synonym. A synonym is simply an
alias, so it requires no storage other than its definition in the data dictionary.

© [email protected] RDBMS Oracle / Page 7 of 125


RDBMS using Oracle
Oracle Database Data Dictionary
Each Oracle database has a data dictionary, which is a set of tables and views that serve as a reference about
the database. For example, a data dictionary stores information about both the logical and physical structure
of the database. A data dictionary also stores the valid users of an Oracle database, information about
integrity constraints defined for tables in the database, and the amount of space allocated for a schema
object and how much of that space is in use, among much other information.
A data dictionary is created when a database is created. To accurately reflect the status of the database at all
times, the data dictionary is automatically updated by Oracle Database in response to specific actions, such
as when the structure of the database is altered. Database users cannot modify the data dictionary. Various
database processes rely on the data dictionary to record, verify, and conduct ongoing work. For example,
during database operation, Oracle Database reads the data dictionary to verify that schema objects exist and
that users have proper access to them.
Oracle Database Instance
An Oracle Database server consists of an Oracle Database and one or more Oracle Database instances. Every
time a database is started, a shared memory area called the system global area (SGA) is allocated and Oracle
Database background processes are started. The combination of the background processes and the SGA is
called an Oracle Database instance.
When users connect to an Oracle Database server, they are connected to an Oracle Database instance. The
database instance services those users by allocating other memory areas in addition to the SGA, and starting
other processes in addition to the Oracle Database background processes.
Accessing the Database
To access the oracle database consider following descriptions:
• Network Connections
• Starting Up the Database
• How Oracle Database Works
Network Connections: Oracle Net Services is the interface between Oracle Database and the network
communication protocols that facilitate distributed processing and distributed databases. Communication
protocols define the way that data is transmitted and received on a network. Oracle Net Services supports
communications on all major network protocols, including TCP/IP, HTTP, FTP, and WebDAV. Using Oracle
Net Services, application developers do not need to be concerned with supporting network communications
in a database application. If a new protocol is used, then the database administrator makes some minor
changes, and the application requires no modifications and continues to function.
Oracle Net, a component of Oracle Net Services, establishes and maintains a network session from a client
application to an Oracle Database server. Once a network session is established, Oracle Net acts as the data
courier for both the client application and the database server, exchanging messages between them. Oracle
Net can perform these jobs because it is located on each computer in the network.
Connecting to a Server
A database user can connect to an Oracle server in one of three ways:
1. The user logs on to the operating system running the Oracle instance and start an application or tool
that accesses the database on that system. The communication pathway is established using the
inter process communication mechanisms available on the host operating system.
2. The user starts the application or tool on a local computer and connects over a network to the
computer running the Oracle database. In this configuration (called client/server), network software
is used to communicate between the user and the back-end server. The client/server architecture

© [email protected] RDBMS Oracle / Page 8 of 125


RDBMS using Oracle
database system has two parts: a front end (client) and a back end (server) connected through a
network. Network software is used to communicate between the user and the Oracle server.
• The client is a database application that initiates a request for an operation to be performed
on the database server. It requests, processes, and presents data managed by the server.
The client workstation can be optimized for its job. For example, the client might not need
large disk capacity, or it might benefit from graphic capabilities. Often, the client runs on a
different computer than the database server. Many clients can simultaneously run against
one server.
• The server runs Oracle Database software and handles the functions required for
concurrent, shared data access. The server receives and processes requests that originate
from client applications. The computer that manages the server can be optimized for its
duties. For example, the server computer can have large disk capacity and fast processors.
3. The user accesses an application server through a tool (such as a Web browser) on the local
computer (client). The application server then interacts with a back-end database server on behalf of
the client.
A traditional multitier architecture has the following components:
• A client or initiator process that starts an operation
• One or more application servers that perform parts of the operation. An application server contains
a large part of the application logic, provides access to the data for the client, and performs some
query processing, thus removing some of the load from the database server. The application server
can serve as an interface between clients and multiple database servers and can provide an
additional level of security.
• An end server or database server that stores most of the data used in the operation
This architecture enables use of an application server to do the following:
• Validate the credentials of a client (such as a Web browser)
• Connect to an Oracle Database server
• Perform the requested operation on behalf of the client.
Starting Up the Database
The three steps to starting an Oracle database and making it available for system are:
• Start an instance.
• Mount the database.
• Open the database.
A database administrator can perform these steps using Oracle Enterprise Manager, the SQL*Plus STARTUP
statement, the srvctl command-line tool, or the Express Edition START command. When Oracle Database
starts an instance, it reads the server parameter file (spfile) or initialization parameter file (pfile) to
determine the values of initialization parameters. Then, it allocates an SGA and creates background
processes.
Connecting to the Database
Connections and sessions are closely related to user processes but are very different in meaning. A
connection is a communication pathway between a user process and an Oracle Database instance. A
communication pathway is established using available interprocess communication mechanisms (on a
computer that runs both the user process and Oracle Database) or network software (when different
computers run the database application and Oracle Database, and communicate through a network).

© [email protected] RDBMS Oracle / Page 9 of 125


RDBMS using Oracle

User Server
SQL> Select … process process
User
Session

Connection

Session

Connecting to the Database


A session represents the state of a current user login to the database instance. For example, when a user
starts SQL*Plus, the user must provide a valid username and password, and then a session is established for
that user. A session lasts from the time a user connects until the user disconnects or exits the database
application.
In the case of a dedicated connection, the session is serviced by a permanent dedicated process. The session
is serviced by an available server process selected from a pool, either by the middle tier or by Oracle shared
server architecture.
Multiple sessions can be created and exist concurrently for a single Oracle database user using the same
username. For example, a user with the username/password of HR/HR can connect to the same Oracle
Database instance several times.
How Oracle Database Works
The following example describes Oracle Database operations at the most basic level. This illustrates an
Oracle Database configuration where the user and associated server process are on separate computers,
connected through a network.
• An instance has started on the computer running Oracle Database, often called the host or database
server.
• A computer running an application (a local computer or client workstation) runs an application in a
user process. The client application attempts to establish a connection to the server using the proper
Oracle Net Services driver.
• The server is running the proper Oracle Net Services driver. The server detects the connection
request from the application and creates a dedicated server process on behalf of the user process.
• The user runs a SQL statement and commits the transaction. For example, the user changes a name
in a row of a table.
• The server process receives the statement and checks the shared pool (an SGA component) for any
shared SQL area that contains a similar SQL statement. If a shared SQL area is found, then the server
process checks the user's access privileges to the requested data, and the existing shared SQL area is
used to process the statement. If not, then a new shared SQL area is allocated for the statement, so
it can be parsed and processed.
• The server process retrieves any necessary data values, either from the actual datafile (table) or
those stored in the SGA.
• The server process modifies data in the system global area. The database writer process (DBWn)
writes modified blocks permanently to disk when doing so is efficient. Because the transaction is
committed, the log writer process (LGWR) immediately records the transaction in the redo log file.

© [email protected] RDBMS Oracle / Page 10 of 125


RDBMS using Oracle

Interacting with an Oracle Database


• If the transaction is successful, then the server process sends a message across the network to the
application. If it is not successful, then an error message is transmitted.
• Throughout this entire procedure, the other background processes run, watching for conditions that
require intervention. In addition, the database server manages other users' transactions and
prevents contention between transactions that request the same data.
Oracle 11G
Oracle Database 11g offers extensive features across the following focus areas:
• Infrastructure Grids: The Infrastructure Grid technology of Oracle enables pooling of low-cost
servers and storage to form systems that deliver the highest quality of service in terms of
manageability, high availability, and performance. Oracle Database 11g consolidates and extends the
benefits of grid computing. Apart from taking full advantage of grid computing, Oracle Database 11g
has unique change assurance features to manage changes in a controlled and cost effective manner.
• Information Management: Oracle Database 11g extends the existing information management
capabilities in content management, information integration, and information life cycle
management areas. Oracle provides content management of advanced data types such as Extensible
Markup Language (XML), text, spatial, multimedia, medical imaging, and semantic technologies.
• Application Development: Oracle Database 11g has capabilities to use and manage all the major
application development environments such as PL/SQL, Java/JDBC, .NET and Windows, PHP, SQL
Developer, and Application Express.
Oracle Database 11g organizations need to support multiple terabytes of information for users who demand
fast and secure access to business applications round-the-clock. The database systems must be reliable and
must be able to recover quickly in the event of any kind of failure. Oracle Database 11g is designed along the
following feature areas to help organizations manage infrastructure grids easily and deliver high-quality
service:
• Manageability: By using some of the change assurance, management automation, and fault
diagnostics features, the database administrators (DBAs) can increase their productivity, reduce
costs, minimize errors, and maximize quality of service. Some of the useful features that promote
better management are Database Replay facility, the SQL Performance Analyzer, and the Automatic
SQL Tuning facility.

© [email protected] RDBMS Oracle / Page 11 of 125


RDBMS using Oracle
• High availability: By using the high availability features, you can reduce the risk of down time and
data loss. These features improve online operations and enable faster database upgrades.
• Performance: By using capabilities such as Secure Files, compression for online transaction
processing (OLTP), Real Application Clusters (RAC) optimizations, Result Caches and so on, you can
greatly improve the performance of your database. Oracle Database 11g enables organizations to
manage large, scalable transactional and data warehousing systems that deliver fast data access
using low-cost modular storage.
• Security: Oracle Database 11g helps organizations protect their information with unique secure
configurations, data encryption and masking, and sophisticated auditing capabilities. It delivers a
secure and scalable platform for reliable and fast access to all types of information by using the
industry-standard interfaces.
• Information integration: Oracle Database 11g has many features to better integrate data
throughout the enterprise. It also supports advanced information life cycle management capabilities.
This helps you manage the changing data in your database.
SQL – Structured Query Language
Structured Query Language (SQL) is the set of statements with which all programs and users access data in
an Oracle database. Application programs and Oracle tools often allow users access to the database without
using SQL directly, but these applications in turn must use SQL when executing the user's request. All major
relational database management systems support SQL, so you can transfer all skills you have gained with
SQL from one database to another. In addition, all programs written in SQL are portable. They can often be
moved from one database to another with very little modification.
Using SQL to Query Your Database
In a relational database, you do not specify the access route to the tables, and you do not need to know how
the data is arranged physically. To access the database, you execute a structured query language (SQL)
statement, which is the American National Standards Institute (ANSI) standard language for operating
relational databases. SQL is a set of statements with which all programs and users access data in an Oracle
database. Application programs and Oracle tools often allow users access to the database without using SQL
directly, but these applications, in turn, must use SQL when executing the user's request. SQL provides
statements for a variety of tasks, including:
• Querying data
• Inserting, updating, and deleting rows in a table
• Creating, replacing, altering, and dropping objects
• Controlling access to the database and its objects
• Guaranteeing database consistency and integrity
SQL unifies all of the preceding tasks in one consistent language and enables you to work with data at a
logical level.
Tools Support
Oracle provides a number of utilities to facilitate your SQL development process:

• Oracle SQL Developer is a graphical tool that lets you browse, create, edit, and delete (drop)
database objects, edit and debug PL/SQL code, run SQL statements and scripts, manipulate and
export data, and create and view reports. With SQL Developer, you can connect to any target Oracle
database schema using standard Oracle database authentication. Once connected, you can perform
operations on objects in the database. You can also connect to schemas for selected third-party
(non-Oracle) databases, such as MySQL, Microsoft SQL Server, and Microsoft Access, view metadata
and data in these databases, and migrate these databases to Oracle.

© [email protected] RDBMS Oracle / Page 12 of 125


RDBMS using Oracle
• SQL*Plus is an interactive and batch query tool that is installed with every Oracle Database server or
client installation. It has a command-line user interface and a web-based user interface called
iSQL*Plus.
• Oracle JDeveloper is a multiple-platform integrated development environment supporting the
complete lifecycle of development for Java, Web services, and SQL. It provides a graphical interface
for executing and tuning SQL statements and a visual schema diagrammer (database modeler). It
also supports editing, compiling, and debugging PL/SQL applications.
• Oracle Application Express is a hosted environment for developing and deploying database-related
Web applications. SQL Workshop is a component of Oracle Application Express that lets you view
and manages database objects from a Web browser. SQL Workshop offers quick access to a SQL
command processor and a SQL script repository. The Oracle Call Interface and Oracle precompilers
let you embed standard SQL statements within a procedure programming language.
• The Oracle Call Interface (OCI) lets you embed SQL statements in C programs. Note: SQL statements
are terminated differently in different programming environments. This documentation set uses the
default SQL*Plus character, the semicolon (;).
SQL Statements
SQL statements supported by Oracle comply with industry standards. Oracle Corporation ensures future
compliance with evolving standards by actively involving key personnel in SQL standards committees. The
industry-accepted committees are ANSI and International Standards Organization (ISO). Both ANSI and ISO
have accepted SQL as the standard language for relational databases. By using the following simple rules and
guidelines, you can construct valid statements that are both easy to read and edit:
• SQL statements are not case-sensitive (unless indicated).
• SQL statements can be entered on one or many lines.
• Keywords cannot be split across lines or abbreviated.
• Clauses are usually placed on separate lines for readability and ease of editing.
• Indents should be used to make code more readable.
• Keywords typically are entered in uppercase; all other words, such as table names and columns
names are entered in lowercase.
SQL statement can be divided into following segments:
Data Definition Language (DDL): statements are used to define the database structure or schema. Some
examples:

• CREATE - to create objects in the database


• ALTER - alters the structure of the database
• DROP - delete objects from the database
• TRUNCATE - remove all records from a table, including all spaces allocated for the records are
removed
• COMMENT - add comments to the data dictionary
• RENAME - rename an object
Data Manipulation Language (DML): statements are used for managing data within schema objects. Some
examples:
• SELECT - retrieve data from the a database
• INSERT - insert data into a table
• UPDATE - updates existing data within a table
• DELETE - deletes all records from a table, the space for the records remain
• MERGE - UPSERT operation (insert or update)

© [email protected] RDBMS Oracle / Page 13 of 125


RDBMS using Oracle
• CALL - call a PL/SQL or Java subprogram
• EXPLAIN PLAN - explain access path to data
• LOCK TABLE - control concurrency
Data Control Language (DCL): statements are use to control the access of data on database by user. Some
examples:

• GRANT - gives user's access privileges to database


• REVOKE - withdraw access privileges given with the GRANT command
Transaction Control (TCL): statements are used to manage the changes made by DML statements. It allows
statements to be grouped together into logical transactions.
• COMMIT - save work done
• SAVEPOINT - identify a point in a transaction to which you can later roll back
• ROLLBACK - restore database to original since the last COMMIT
• SET TRANSACTION - Change transaction options like isolation level and what rollback segment to use
Session Control Statements
Session control statements dynamically manage the properties of a user session. These statements do not
implicitly commit the current transaction. PL/SQL does not support session control statements. Some
examples are:
• ALTER SESSION
• SET ROLE
System Control Statement
The single system control statement, ALTER SYSTEM, dynamically manages the properties of an Oracle
database instance. This statement does not implicitly commit the current transaction and is not supported in
PL/SQL.
Embedded SQL Statements
Embedded SQL statements place DDL, DML, and transaction control statements within a procedural
language program. Embedded SQL is supported by the Oracle pre-compilers:
• Pro*COBOL Programmer's Guide
• Pro*C/C++ Programmer's Guide
• Oracle SQL*Module for Ada Programmer's Guide.
SQL Statements in SQL*Plus
Oracle SQL*Plus is a command-line interface with which you can submit SQL statements and PL/SQL blocks
for execution and receive the results in an application or command window. SQL*Plus is shipped with the
database. It is installed on a client and on the database server system and can be accessed through from an
icon or the command line.
SQL*Plus is an environment in which you can execute SQL statements to retrieve, modify, add, and remove
data from the database. Format, perform calculations on, store, and print query results in the form of
reports. Create script files to store SQL statements for repeated use in the future.
To log in from a command-line environment, perform the following steps:
1. Enter the SQL*Plus command and optionally enter your username, password (your password is
visible if you enter it here), and the database connect string.
2. In a Windows environment, you can set up an icon for SQL*Plus or click Start > Run >
oracle_home\product\11.1.0\client_1\BIN\sqlplus.exe.

© [email protected] RDBMS Oracle / Page 14 of 125


RDBMS using Oracle
To ensure the integrity of your password, do not enter it at the operating system prompt. Instead, enter only
your username. Enter your password at the password prompt. After you log in to SQL*Plus, you see the
message shown in the screenshot in the figure below, provided you are using SQL*Plus version 11.1.0.4.0.

What Is Oracle SQL Developer?


Oracle SQL Developer is a free graphical tool designed to improve your productivity and simplify the
development of everyday database tasks. With just a few clicks, you can easily create and debug stored
procedures, test SQL statements, and view optimizer plans.
SQL Developer, the visual tool for database development, simplifies the following tasks:
• Browsing and managing database objects
• Executing SQL statements and scripts
• Editing and debugging PL/SQL statements
• Creating reports
You can connect to any target Oracle database schema using the standard Oracle database authentication.
When connected, you can perform operations on objects in the database. To start SQL Developer, go to
<local drive>:\SQL Developer and double-click sqldeveloper.exe or use Start All Programs  Oracle Home
Application developmentSQL Developer from Windows XP desktop.

© [email protected] RDBMS Oracle / Page 15 of 125


RDBMS using Oracle

You must have at least one database connection to use SQL Developer. You can create and test connections
for:
• Multiple databases
• Multiple schemas
SQL Developer automatically reads any connections defined in the tnsnames.ora file on your system. You
can export connections to an XML file. Each additional database connection created is listed in the
Connections navigator hierarchy.
Creating a Database Connection
To create a database connection, start SQL Developer and perform the following steps:
1. On the Connections tabbed page, right-click Connections and select New Connection.
2. Enter the connection name, username, password, host name, and system identifier (SID) or
Service name for the database that you want to connect to.
3. Click Test to make sure that the connection has been set correctly.
4. Click Connect.
On the Oracle tabbed page, at the bottom, enter the following options:
• Hostname: The host system for the Oracle database
• Port: Listener port
• SID: Database name
• Service name: Network service name for a remote database connection

© [email protected] RDBMS Oracle / Page 16 of 125


RDBMS using Oracle
If you select the Save Password check box, the password is saved to an XML file. Therefore, the next time
you access the SQL Developer connection, you will not be prompted for the password. The other tabbed
pages enable you to set up connections to non-Oracle databases.

Browse Data using SQL Developer.

Using SQL Worksheet


When you connect to a database, a SQL Worksheet window for that connection is automatically opened. You
can use SQL Worksheet to enter and execute SQL, PL/SQL, and SQL*Plus statements. SQL Worksheet
supports SQL*Plus statements to a certain extent. SQL*Plus statements that are not supported by SQL
Worksheet are ignored and not passed to the database.
You can specify any actions that can be processed by the database connection associated with the
worksheet, such as creating a table, inserting data, creating and editing a trigger, selecting data from a table,
saving the selected data to a file, and saving and running SQL scripts.

© [email protected] RDBMS Oracle / Page 17 of 125


RDBMS using Oracle
You can display a SQL worksheet by using any of the following two options:
Select Tools > SQL Worksheet. Click the Open SQL Worksheet icon. You can set your preferences so that the
SQL Worksheet is opened automatically when you have a database connection.
Select Tools > Preferences. Click Database. Click Worksheet Parameters. Check Open a Worksheet on
Connect.

You may want to use the shortcut keys or icons to perform certain tasks such as executing a SQL statement,
running a script, and viewing the history of SQL statements that you have executed. You can use the SQL
Worksheet toolbar that contains icons to perform the following tasks:
1. Execute Statement: Executes
the statement at the cursor in the
Enter SQL Statement box.
2. Run Script: Executes all
statements in the Enter SQL
Statement box using Script Runner.
3. Commit: Writes any changes
to the database and ends the
transaction
4. Rollback: Discards any
changes to the database, without
writing them to the database, and
ends the transaction
5. Cancel: Stops the execution of
current statement.
6. SQL History: Displays a dialog
box with information about the
SQL statements that you have
executed
7. Execute Explain Plan: Generates the execution plan, which you can see by clicking the Explain tab
8. Autotrace: Generates trace information for the statement
9. Clear: Erases the statement or statements in the Enter SQL Statement box
Executing SQL Statements
In SQL Worksheet, you can use the Enter SQL Statement box to enter a single SQL statement or multiple SQL
statements. For a single statement, the semicolon at the end is optional. When you enter the statement, the
SQL keywords are automatically highlighted. To execute a SQL statement, ensure that your cursor is within
the statement and click the Execute Statement icon. Alternatively, you can press the [F9] key. To execute

© [email protected] RDBMS Oracle / Page 18 of 125


RDBMS using Oracle
multiple SQL statements and see the results, click the Run Script icon. Alternatively, you can press the F5
key.
In the example there are multiple SQL statements; the first statement is terminated with a semicolon. The
cursor is in the first statement and so when the statement is executed, results corresponding to the first
statement are displayed in the Results box.

Saving SQL Scripts


You can save your SQL statements from the SQL Worksheet into a text file. To save the contents of the Enter
SQL Statement text box, follow these steps:
1. Click the Save icon or use the File > Save menu item.
2. In the Windows Save dialog box, enter a file name and the location where you want the file
saved.
3. Click Save.
After you save the contents to a file, the Enter SQL Statement text box displays a tabbed page of your file
contents. You can have multiple files open at once. Each file displays as a tabbed page.
Script Pathing
You can select a default path to look for scripts and to save scripts. Under Tools > Preferences > Database >
Worksheet Parameters, enter a value in the Select default path to look for scripts field.

© [email protected] RDBMS Oracle / Page 19 of 125


RDBMS using Oracle

Running a Saved SQL Script


To run a saved SQL script, follow these steps:
1. In the Enter SQL Statement window, use the @ command, followed by the location and name of
the file that you want to run.
2. Click the Run Script icon.
The results from running the file are displayed on the Script Output tabbed page. You can also save the script
output by clicking the Save icon on the Script Output tabbed page. The Windows File Save dialog box
appears and you can identify a name and location for your file.
Note: You can also right-click in the Enter SQL Statement area and select Open File from the shortcut menu.

© [email protected] RDBMS Oracle / Page 20 of 125


RDBMS using Oracle
Strart with SQL *Plus
SQL*Plus is an interactive and batch query tool that is installed with every Oracle Database server or client
installation. It has a command-line user interface and a web-based user interface called iSQL*Plus. Here we
will start with SQL *Plus command-line user interface.
In a Windows environment, you can set up an icon for SQL*Plus or click:
Start > Run > oracle_home\product\11.1.0\client_1\BIN\sqlplus.exe.
A window appears as:

Here you have to use a user name provided by your Database Administrator. Here we are creating a new
user to work upon. Even for this we have to login into some DBA user using:
Enter user-name: SYSTEM as SYSDBA
Enter Password: MANAGER (will not be displayed on screen)
You will get SQL> prompt as

© [email protected] RDBMS Oracle / Page 21 of 125


RDBMS using Oracle
This is the place where we have to create a new user. Try following steps. Commands used in SQL are case
insensitive. Type in
SQL> create use India identified by india;
User created.
SQL> grant DBA to INDIA;
Grant succeeded.
SQL> Commit;
Commit complete.
SQL> Connect india
Enter password: india
Connected.
SQL> show user
USER is "INDIA"
SQL>
Now by following above steps we have created a user named INDIA and its password is INDIA. Then we had
given DBA rights to INDIA user using grant DBA to INDIA; command and committed the transaction. Further
we got connected with india. Later on you can directly get connected to your user at the first login prompt
available as you start SQL *Plus. Similarly you can have your own user and password. Here we suggest you
not to use any default users provided while installation of oracle. Here is a short description of the
commands we had used.
CREATE USER command allows us to create a new user.
GRANT command allows us to issue privileges to an existing user.
COMMIT command ensure the transaction to be completed on database.
CONNECT command used to login in to a user. After connection your work done is under that user only.
SHOW USER command displays the user name to which we got connected.
CLEAR SCREEN command clears the SQL screen contents.
EDIT command allows us to make modifications in last given command resides in SQL buffer.
/ command is used to fire the command resides into SQL buffer.
EXIT or QUIT command is used to close SQL *Plus application.
You might get typing mistakes while typing commands. To edit them you can use line by line history using up
arrow key or use EDIT command. It will invoke last given command into notepad editor there you can edit it
and use File exit by saving. Again you will get SQL> prompt. Use the / (Forward Slash) to run the command.

© [email protected] RDBMS Oracle / Page 22 of 125


RDBMS using Oracle

Before starting command and queries consider few points:


• SQL statements are not case-sensitive.
• SQL statements can be entered on one or more lines.
• Keywords cannot be abbreviated or split across lines.
• Clauses are usually placed on separate lines.
• Indents are used to enhance readability.
• In SQL Developer, SQL statements can optionally be terminated by a semicolon (;). Semicolons are
required when you execute multiple SQL statements.
• In SQL*Plus, you are required to end each SQL statement with a semicolon (;).
Using Oracle Objects
Oracle Database provides an organized mechanism for storing, managing, and retrieving information. Tables
are the basic storage structure for holding business data. So first of all you learn how to create tables and
work with them. You may want to modify data entered in tables. You may also want to maintain integrity
with the data. Sometimes, you may want to remove tables that are no longer useful. A table is uniquely
identified by its name and consists of rows that contain the stored information, each row containing exactly
one tuple (or record). A table can have one or more columns. A column is made up of a column name and a
data type, and it describes an attribute of the tuples. The structure of a table, also called relation schema,
thus is defined by its attributes. The type of information to be stored in a table is defined by the data types
of the attributes at table creation time.
Creating Table
The CREATE TABLE command allows us to create a table as in given example.
CREATE TABLE PERSON
(
PERNO number(5),
PNAME varchar2(20),
ADDRESS varchar2(30),
CITY varchar2(20),
PHONE number(10),
DOB date,
SALARY number(12,2)
);
When creating tables, you must provide:

• Table name
• Column name(s)
• Data types for each column
A table can have up to 254 columns which may have different or same data types and sets of values
(domains), respectively. Possible domains are alphanumeric data (strings), numbers and date formats. A
Table name or Column names must start with any of these alphabet, number, _ , # , $. Better to start with an
alphabet only. Must be 1 to 30 character long and it should not be a reserve word of Oracle – SQL.
Data Type
A data type denotes what type of data we are going to collect into a column or we can say a nature of data
been collected into column. Here is a list of common data type used in SQL.

© [email protected] RDBMS Oracle / Page 23 of 125


RDBMS using Oracle
Char: CHAR [(size [BYTE | CHAR])] Fixed-length character data of length size bytes or characters. Maximum
size is 2000 bytes or characters. Default and minimum size is 1 byte. Example: ECODE char(4).
Varchar2: VARCHAR2(size [BYTE | CHAR]) Variable-length character string having maximum length size
bytes or characters. Maximum size is 4000 bytes or characters, and minimum is 1 byte or 1 character. You
must specify size for VARCHAR2. Example: BookName varchar2(20).
Number: NUMBER [ (p [, s]) ] Number having precision p and scale s. The precision p can range from 1 to 38.
The scale s can range from -84 to 127. Both precision and scale are in decimal digits. A NUMBER value
requires from 1 to 22 bytes. Examples: number(8), number(5,2) Note that, e.g., number(5,2) cannot contain
anything larger than 999.99 without resulting in an error. Data types derived from number are int[eger],
dec[imal], smallint and real.
Date: DATE Valid date range from January 1, 4712 BC, to December 31, 9999 AD. The default format is
dd-Mon-yy. The size is fixed at 7 bytes. This datatype contains the datetime fields YEAR, MONTH, DAY,
HOUR, MINUTE, and SECOND. It does not have fractional seconds or a time zone.
LONG RAW: Raw binary data of variable length up to 2 gigabytes. Used for images and other media files.
There are few more extra data types are also used. Such as
NVARCHAR2: NVARCHAR2(size) Variable-length Unicode character string having maximum length size
characters. The number of bytes can be up to two times size for AL16UTF16 encoding and three times size
for UTF8 encoding. Maximum size is determined by the national character set definition, with an upper limit
of 4000 bytes. You must specify size for NVARCHAR2.
TIMESTAMP: Year, month, and day values of date, as well as hour, minute, and second values of time, where
fractional_seconds_precision is the number of digits in the fractional part of the SECOND datetime field.
Accepted values of fractional_seconds_precision are 0 to 9. The default is 6. The default format is
determined explicitly by the NLS_DATE_FORMAT parameter or implicitly by the NLS_TERRITORY parameter.
The sizes varies from 7 to 11 bytes, depending on the precision. This datatype contains the datetime fields
YEAR, MONTH, DAY, HOUR, MINUTE, and SECOND. Data is normalized to the database time zone when it is
stored in the database. When the data is retrieved, users see the data in the session time zone. The default
format is determined explicitly by the NLS_DATE_FORMAT parameter or implicitly by the NLS_TERRITORY
parameter. The sizes varies from 7 to 11 bytes, depending on the precision.
User-Defined Types: User-defined datatypes use Oracle built-in datatypes and other user-defined datatypes
as the building blocks of object types that model the structure and behavior of data in applications.
Datatype Precedence
Oracle uses datatype precedence to determine implicit datatype conversion. Oracle datatypes take the
following precedence:
• Datetime and interval datatypes
• BINARY_DOUBLE
• BINARY_FLOAT
• NUMBER
• Character datatypes
• All other built-in datatypes
Literals
The terms literal and constant value are synonymous and refer to a fixed data value. For example, 'JACK',
'BLUE ISLAND', and '101' are all character literals; 5001 is a numeric literal. Character literals are enclosed in
single quotation marks so that Oracle can distinguish them from schema object names. Many SQL

© [email protected] RDBMS Oracle / Page 24 of 125


RDBMS using Oracle
statements and functions require you to specify character and numeric literal values. You can also specify
literals as part of expressions and conditions.
Here are some valid text literals:
'Hello' 'ORACLE.dbs' 'Jackie''s raincoat' '09-MAR-98'
Here are some valid numeric literals
25 +6.34 0.5 25e-03 -1
Here are some datetime literals
DATE '2002-10-03' TO_DATE('3-OCT-2002','DD-MON-YYYY') TIMESTAMP '1997-01-31 09:26:50.124'
By using above description you can build table of your choice. Now we have to create rows of table i.e. insert
data into table.
INSERT: The insert command is used to create rows in table. In SQL we can have only one row at a time using
insert.
SQL> INSERT INTO person VALUES (1001, 'Ram Kumar', '201, A Nagar', 'Hyderabad', 2345678, '10-April-67',
15000);
1 row created
Likewise you can create more rows. But only one row at a time. Here it is compulsory to use values for each
column. If you want to leave some values in columns then you have to specify insert in a column specified
manner as.
SQL> INSERT INTO person(perno, pname, salary) VALUES (1002, 'Shyam Lal', 25000);
1 row created
SQL>
You can insert more than one row at a time using substitutions in command line as:
SQL> INSERT INTO person VALUES ( &PERNO, '&PNAME', '&ADDRESS', '&CITY', '&PHONE', '&DOB', &SALARY);
Enter value for perno: 1003
Enter value for pname: Hari Singh
Enter value for address: Shanti Niketan, 3rd Flat
Enter value for city: Hyderabad
Enter value for phone: 2414109
Enter value for dob: 15-Nov-86
Enter value for salary: 12500.75
old 1: INSERT INTO person VALUES ( &PERNO, '&PNAME', '&ADDRESS', '&CITY', '&PHONE', '&DOB',
&SALARY)
new 1: INSERT INTO person VALUES ( 1003, 'Hari Singh', 'Shanti Niketan, 3rd Flat', 'Hyderabad', '2414109',
'15-Nov-86', 12500.75)

1 row created.
SQL> /
Enter value for perno: 1004
Enter value for pname: Anil Jain
Enter value for address: 123, 4 lane, Shah Pura
Enter value for city: New Delhi
Enter value for phone: 27878876
Enter value for dob: 12-Dec-71
Enter value for salary: 12500.50
© [email protected] RDBMS Oracle / Page 25 of 125
RDBMS using Oracle
old 1: INSERT INTO person VALUES ( &PERNO, '&PNAME', '&ADDRESS', '&CITY', '&PHONE', '&DOB',
&SALARY)
new 1: INSERT INTO person VALUES ( 1004, 'Anil Jain', '123, 4 lane, Shah Pura', 'New Delhi', '27878876', '12-
Dec-71', 12500.50)

1 row created.
SQL>
DESCRIBE: A describe command is used to display structure of table on screen as:
SQL> desc person
Name Null? Type
----------------------------------------- -------- ---------------------
PERNO NUMBER(5)
PNAME VARCHAR2(20)
ADDRESS VARCHAR2(30)
CITY VARCHAR2(20)
PHONE NUMBER(10)
DOB DATE
SALARY NUMBER(12,2)
SQL>
SELECT: In order to retrieve the information stored in the database, the SQL query language is used. Select
Command is used to query data from tables or views. The basic SELECT statement has four basic parts.
• The word 'SELECT' followed by what you want to see. That is a list of columns or * for all columns.
• The word 'FROM' followed by one or more table names from which we want to view rows.
The above two are mandatory sections of the select command.
• The word 'WHERE' followed by a condition that restrict row display for some criteria.
• The clause 'ORDER BY' followed by sorting criteria i.e. a list of columns used to arrange displayed
rows in a specific order (Ascending or descending).
In its simplest form, a SELECT statement could be written as
SQL> select * from person;

© [email protected] RDBMS Oracle / Page 26 of 125


RDBMS using Oracle
The display could be unorganized as shown in the figure above. It depends on set commands. Use Show
command system displays current values setup as:
SQL> show linesize pagesize
linesize 80
pagesize 14

If you want you can change those using SET commands as


SQL>set linesize 100
SQL>set pagesize 50
Now the same command will display

A SELECT statement retrieves information from the database. With a SELECT statement, you can use the
following capabilities:
• Projection: Select the columns in a table that are returned by a query. Select as few or as many of
the columns as required.
• Selection: Select the rows in a table that are returned by a query. Various criteria can be used to
restrict the rows that are retrieved.
• Joining: Bring together data that is stored in different tables by specifying the link between them.

© [email protected] RDBMS Oracle / Page 27 of 125


RDBMS using Oracle
You can use the SELECT statement to display specific columns of the table by specifying the column names,
separated by commas.
SQL> select perno, pname, salary from person;
It will display rows as

Now I hope that you understand how to create a simple table and to insert rows into it. But Oracle – SQL is
not used only for maintaining simple tables as we have done. They provide us a secured way to maintain our
data using constraints.
Constraints
A constraint is a rule that restricts the values in a database. Oracle Database lets you create six types of
constraints and lets you declare them syntactically in two ways.
• As part of the definition of an individual column or attribute. This is called inline specification or
column level constraints.
• As part of the table definition. This is called out-of-line specification or table level constraint. Table
level constraint can also be applied during modification of table design (Alter Table). It is customary
to use table level constraint for defining composite keys.
Constraints Types
PRIMARY KEY: A primary key constraint combines a NOT NULL constraint and a unique constraint in a single
declaration. It prohibits multiple rows from having the same value in the same column or combination of
columns and prohibits values from being null.
UNIQUE: A unique constraint prohibits multiple rows from having the same value in the same column or
combination of columns but allows some values to be null.
NOT NULL: A NOT NULL constraint prohibits a database value from being null.
FOREIGN KEY: A foreign key constraint requires values in one table to match values in another table.
CHECK: A check constraint requires a value in the database to comply with a specified condition.
REF: A REF column by definition references an object in another object type or in a relational table. A REF
constraint lets you further describe the relationship between the REF column and the object it references.
Defining Constraints
You must have the privileges necessary to issue the statement in which you are defining the constraint. The
NOT NULL constraints must be declared inline. All other constraints can be declared either inline or out of
line. To create a foreign key constraint, in addition, the parent table or view must be in your own schema or
you must have the REFERENCES privilege on the columns of the referenced key in the parent table or view.
Oracle stores the name and the definition of the integrity constraint in the USER_ CONSTRAINTS, ALL_
CONSTRAINTS, and DBA_CONSTRAINTS data dictionary views (in the CONSTRAINT_NAME and SEARCH_
CONDITION columns, respectively).
© [email protected] RDBMS Oracle / Page 28 of 125
RDBMS using Oracle
Oracle Database does not support constraints on columns or attributes whose type is a user-defined object,
nested table, VARRAY, REF, or LOB, with two exceptions:

• NOT NULL constraints are supported for a column or attribute whose type is user-defined object,
VARRAY, REF, or LOB.
• NOT NULL, foreign key, and REF constraints are supported on a column of type REF.
CONSTRAINT constraint_name Specify a name for the constraint. If you omit this identifier, then Oracle
Database generates a name with the form SYS_C<number>.
Before defining constraints let's discuss an example of Library system having three sample tables BOOK,
MEMBER and TRANS. Following are the create table commands to apply constraints on columns of tables.
SQL> create table book
( bcode number(5) constraint bcd_pk primary key,
bname varchar2(20) not null,
author varchar2(20),
price number(10,2),
edition number(4),
status char(2) constraint bksts_chk check (status in('AV','IS','LS','DM')));
Table created.
SQL>create table member
( mcode number(5) constraint mcd_pk primary key,
mname varchar2(20) not null,
address varchar2(20),
phone number(10),
dt_of_mship date,
mfee number(10,2),
bank_acno number(16) constraint bankNo_uk unique,
status char(4) constraint mem_st_chk check (status in('CONT','LEFT','SUSP','TERM')));
Table created.
SQL> create table trans
(trcode number(5) constraint tcd_pk primary key,
bcode number(5) constraint bcd_book_FK references book(bcode),
mcode number(5) constraint mbcd_mem_FK references member(mcode),
idate date,
ldate date,
sdate date,
charges number(10,2) constraint charge_chk check(charges>20));
Table created.
NOTE : See the table list using following select command - SQL>select * from TAB;
SQL> select * from tab;

© [email protected] RDBMS Oracle / Page 29 of 125


RDBMS using Oracle
Try to make following tables and also insert sufficient rows so that queries can be applied in SQL.
Human Resources (HR) Data Set
The Human Resources (HR) schema is part of the Oracle Common Schema that can be installed in an Oracle
database. Most of the queries used in this course will use data from the HR schema.
Table Descriptions
REGIONS contains rows representing a region (such as Americas, Asia, and so on).
COUNTRIES contains rows for countries, each of which are associated with a region.
LOCATIONS contains the addresses of specific offices, warehouses, and/or production sites of a company in a
particular country.
DEPARTMENTS shows details of the departments in which employees work. Each department can have a
relationship representing the department manager in the EMPLOYEES table.
EMPLOYEES contains details about each employee who works for a department. Some employees may not
be assigned to any department.
JOBS contains the job types that can be held by each employee.
JOB_HISTORY contains the job history of the employees. If an employee changes departments within the job
or changes jobs within the department, a new row is inserted in this table with the old job information of the
employee.

REGIONS Table Description Regions Table Sample Data


Column Name Null? Type 1,'Europe'
2,'Americas'
REGION_ID NOT NULL NUMBER 3,'Asia'
REGION_NAME VARCHAR2(25) 4,'Africa'
5,'Australia'
CREATE TABLE regions 6,'Middle East'
( 7,'USSR'
region_id NUMBER constraint reg_id_pk
PRIMARY KEY,
region_name VARCHAR2(25)
);
© [email protected] RDBMS Oracle / Page 30 of 125
RDBMS using Oracle
Countries Table Sample Data
COUNTRIES Table Description
'AR','Argentina',2
Column Name Null? Type 'AU','Australia',3
COUNTRY_ID NOT NULL CHAR(2) 'BE','Belgium',1
'BR','Brazil',2
COUNTRY_NAME VARCHAR2(40) 'CA','Canada',2
REGION_ID NUMBER 'CH','Switzerland',1
'CN','China',3
CREATE TABLE countries 'DE','Germany',1
( 'DK','Denmark',1
country_id CHAR(2) constraint country_id_pk 'EG','Egypt',4
PRIMARY KEY, 'FR','France',1
country_name VARCHAR2(40), 'HK','HongKong',3
region_id NUMBER constraint reg_id_fk 'IL','Israel',4
REFERENCES regions(region_id) 'IN','India',3
);

Locations Table Sample Data


LOCATIONS Table Description
1000,'1297 Via Cola di Rie','00989','Roma',null,'IT'
Column Name Null? Type 1100,'93091 Calle della
LOCATION_ID NOT NULL NUMBER(4) Testa','10934','Venice',null,'IT'
1200,'2017 Shinjuku-ku','1689','Tokyo','Tokyo
STREET_ADDRESS VARCHAR2(40) Prefecture', 'JP'
POSTAL_CODE VARCHAR2(12) 1300,'9450 Kamiya-cho','6823','Hiroshima',null,'JP'
1400,'2014 Jabberwocky Rd', '26192',
CITY NOT NULL VARCHAR2(30) 'Southlake','Texas', 'US'
STATE_PROVINCE VARCHAR2(25) 1500,'2011 Interiors Blvd','99236','South San
Francisco','California','US'
COUNTRY_ID CHAR(2) 1600,'2007 Zagora St','50090','South
Brunswick','New Jersey','US'
CREATE TABLE locations 1700,'2004 Charade
( Rd','98199','Seattle','Washington','US'
location_id NUMBER(4) CONSTRAINT 1800,'147 Spadina Ave','M5V
loc_id_pk 2L7','Toronto','Ontario','CA'
PRIMARY KEY, 1900,'6092 Boxwood St','YSW
street_address VARCHAR2(40), 9T2','Whitehorse','Yukon','CA'
postal_code VARCHAR2(12), 2000,'40-5-12
city VARCHAR2(30) NOT NULL, Laogianggen','190518','Beijing',null,'CN'
state_province VARCHAR2(25), 2100,'1298 Vileparle
country_id CHAR(2) CONSTRAINT E)','490231','Bombay','Maharashtra','IN'
loc_c_id_fk 2200,'12-98 Victoria Street','2901','Sydney','New
REFERENCES countries(country_id) South Wales','AU'
);
DEPARTMENTS Table Description Departments Table Sample Data
Column Name Null? Type 10,'Administration',200,1700
DEPARTMENT_ID NOT NULL NUMBER(4) 20,'Marketing',201,1800
30,'Purchasing',114,1700
DEPARTMENT_NAME NOT NULL VARCHAR2(30)
40,'Human Resources',203,2400
MANAGER_ID NUMBER(6) 50,'Shipping',121,1500
LOCATION_ID NUMBER(4) 60,'IT',103,1400
CREATE TABLE departments 70,'Public Relations',204,2700
( 80,'Sales',145,2500
department_id NUMBER(4) constraint 90,'Executive',100,1700
dept_id_pk PRIMARY KEY, 100,'Finance',108,1700
department_name VARCHAR2(30) NOT NULL, 110,'Accounting',205,1700
manager_id NUMBER(6), 120,'Treasury',null,1700
location_id NUMBER(4) constraints 130,'Corporate Tax',null,1700

© [email protected] RDBMS Oracle / Page 31 of 125


RDBMS using Oracle
dept_loc_fk REFERENCES locations 140,'Control And Credit',null,1700
(location_id) 150,'Shareholder Services',null,1700
);

JOBS Table Description Jobs Table Sample Data


Column Name Null? Type 'AD_PRES','President',20000,40000
'AD_VP','Administration Vice
JOB_ID NOT NULL VARCHAR2(10) President',15000,30000
JOB_TITLE NOT NULL VARCHAR2(35) 'AD_ASST','Administration Assistant',3000,6000
'FI_MGR','Finance Manager',8200,16000
MIN_SALARY NUMBER(6) 'FI_ACCOUNT','Accountant',4200,9000
MAX_SALARY NUMBER(6) 'AC_MGR','Accounting Manager',8200,16000
CREATE TABLE jobs 'AC_ACCOUNT','Public Accountant',4200,9000
( 'SA_MAN','Sales Manager',10000,20000
job_id VARCHAR2(10) constraint job_id_fk 'SA_REP','Sales Representative',6000,12000
PRIMARY KEY, 'PU_MAN','Purchasing Manager',8000,15000
job_title VARCHAR2(35) NOT NULL, 'PU_CLERK','Purchasing Clerk',2500,5500
min_salary NUMBER(6), 'ST_MAN','Stock Manager',5500,8500
max_salary NUMBER(6) 'ST_CLERK','Stock Clerk',2000,5000
); 'SH_CLERK','Shipping Clerk',2500,5500
'IT_PROG','Programmer',4000,10000
EMPLOYEES Table Description Employee Table Sample Data
Column Name Null? Type 198,'Donald','OConnell','DOCONNEL','650.507.9833'
EMPLOYEE_ID NOT NULL NUMBER(6) ,to_timestamp('21-JUN-99','DD-MON-RR
HH.MI.SSXFF AM'),'SH_CLERK',2600,null,124,50
FIRST_NAME VARCHAR2(20)
199,'Douglas','Grant','DGRANT','650.507.9844',to_ti
LAST_NAME NOT NULL VARCHAR2(25)
mestamp('13-JAN-00','DD-MON-RR HH.MI.SSXFF
EMAIL NOT NULL VARCHAR2(20) AM'),'SH_CLERK',2600,null,124,50
PHONE_NUMBER VARCHAR2(20) 200,'Jennifer','Whalen','JWHALEN','515.123.4444',t
HIRE_DATE NOT NULL DATE o_timestamp('17-SEP-87','DD-MON-RR HH.MI.SSXFF
AM'),'AD_ASST',4400,null,101,10
JOB_ID NOT NULL VARCHAR2(10)
201,'Michael','Hartstein','MHARTSTE','515.123.5555
SALARY NUMBER(8,2) ',to_timestamp('17-FEB-96','DD-MON-RR
COMMISSION_PCT NUMBER(2,2) HH.MI.SSXFF AM'),'MK_MAN',13000,null,100,20
MANAGER_ID NUMBER(6) 202,'Pat','Fay','PFAY','603.123.6666',to_timestamp('
17-AUG-97','DD-MON-RR HH.MI.SSXFF
DEPARTMENT_ID NUMBER(4) AM'),'MK_REP',6000,null,201,20
CREATE TABLE employees 203,'Susan','Mavris','SMAVRIS','515.123.7777',to_ti
( mestamp('07-JUN-94','DD-MON-RR HH.MI.SSXFF
employee_id NUMBER(6) CONSTRAINT AM'),'HR_REP',6500,null,101,40
emp_emp_id_pk PRIMARY KEY,
204,'Hermann','Baer','HBAER','515.123.8888',to_ti
first_name VARCHAR2(20),
mestamp('07-JUN-94','DD-MON-RR HH.MI.SSXFF
last_name VARCHAR2(25) NOT NULL,
AM'),'PR_REP',10000,null,101,70
email VARCHAR2(25) NOT NULL CONSTRAINT
emp_email_uk UNIQUE, 205,'Shelley','Higgins','SHIGGINS','515.123.8080',to_
phone_number VARCHAR2(20), timestamp('07-JUN-94','DD-MON-RR HH.MI.SSXFF
hire_date DATE NOT NULL, AM'),'AC_MGR',12000,null,101,110
job_id VARCHAR2(10) NOT NULL CONSTRAINT 206,'William','Gietz','WGIETZ','515.123.8181',to_tim
emp_job_fk REFERENCES jobs (job_id), estamp('07-JUN-94','DD-MON-RR HH.MI.SSXFF
salary NUMBER(8,2) CONSTRAINT AM'),'AC_ACCOUNT',8300,null,205,110
emp_salary_min CHECK (salary > 0), 100,'Steven','King','SKING','515.123.4567',to_timest
commission_pct NUMBER(2,2), amp('17-JUN-87','DD-MON-RR HH.MI.SSXFF
manager_id NUMBER(6) CONSTRAINT AM'),'AD_PRES',24000,null,null,90
emp_manager_fk REFERENCES 101,'Neena','Kochhar','NKOCHHAR','515.123.4568',t
employees(employee_id),
© [email protected] RDBMS Oracle / Page 32 of 125
RDBMS using Oracle
department_id NUMBER(4) CONSTRAINT o_timestamp('21-SEP-89','DD-MON-RR HH.MI.SSXFF
emp_dept_fk REFERENCES AM'),'AD_VP',17000,null,100,90
departments(department_id) 102,'Lex','De
);

JOB_HISTORY Table Description Job_history Table Sample Data


Column Name Null? Type 102,to_timestamp('13-JAN-93','DD-MON-RR
EMPLOYEE_ID NOT NULL NUMBER(6) HH.MI.SSXFF AM'),to_timestamp('24-JUL-98','DD-
MON-RR HH.MI.SSXFF AM'),'IT_PROG',60
START_DATE NOT NULL DATE
101,to_timestamp('21-SEP-89','DD-MON-RR
END_DATE NOT NULL DATE HH.MI.SSXFF AM'),to_timestamp('27-OCT-93','DD-
JOB_ID NOT NULL VARCHAR2(10) MON-RR HH.MI.SSXFF AM'),'AC_ACCOUNT',110
101,to_timestamp('28-OCT-93','DD-MON-RR
DEPARTMENT_ID NUMBER(4) HH.MI.SSXFF AM'),to_timestamp('15-MAR-97','DD-
CREATE TABLE job_history MON-RR HH.MI.SSXFF AM'),'AC_MGR',110
( 201,to_timestamp('17-FEB-96','DD-MON-RR
employee_id NUMBER(6) NOT NULL HH.MI.SSXFF AM'),to_timestamp('19-DEC-99','DD-
CONSTRAINT jhist_emp_fk REFERENCES MON-RR HH.MI.SSXFF AM'),'MK_REP',20
employees(employee_id),
114,to_timestamp('24-MAR-98','DD-MON-RR
start_date DATE NOT NULL,
HH.MI.SSXFF AM'),to_timestamp('31-DEC-99','DD-
end_date DATE NOT NULL,
MON-RR HH.MI.SSXFF AM'),'ST_CLERK',50
job_id VARCHAR2(10) NOT NULL
CONSTRAINT jhist_job_fk REFERENCES 122,to_timestamp('01-JAN-99','DD-MON-RR
jobs(job_id), HH.MI.SSXFF AM'),to_timestamp('31-DEC-99','DD-
department_id NUMBER(4) CONSTRAINT MON-RR HH.MI.SSXFF AM'),'ST_CLERK',50
jhist_dept_fk REFERENCES 200,to_timestamp('17-SEP-87','DD-MON-RR
departments(department_id), HH.MI.SSXFF AM'),to_timestamp('17-JUN-93','DD-
CONSTRAINT jhist_date_interval CHECK MON-RR HH.MI.SSXFF AM'),'AD_ASST',90
(end_date > start_date), 176,to_timestamp('24-MAR-98','DD-MON-RR
CONSTRAINT jhist_emp_id_st_date_pk HH.MI.SSXFF AM'),to_timestamp('31-DEC-98','DD-
PRIMARY KEY (employee_id, start_date) MON-RR HH.MI.SSXFF AM'),'SA_REP',80
);

Note : It's not necessary that you use the data above. You can insert your own data. If you want you can
have data from HR user under sys sysdba. To access data you can also use SQL Developer as shown below.

© [email protected] RDBMS Oracle / Page 33 of 125


RDBMS using Oracle
Retrieving Data Using the SQL SELECT Statement
SELECT * FROM departments;
You can display all columns of data in a table by following the SELECT keyword with an asterisk (*). It
produces department list with all columns of departments table.
SELECT department_id, location_id FROM departments;
You can use the SELECT statement to display specific columns of the table by specifying the column names,
separated by commas.
Arithmetic Expressions
You may need to modify the way in which data is displayed, or you may want to perform calculations, or look
at what-if scenarios. All these are possible using arithmetic expressions. An arithmetic expression can
contain column names, constant numeric values, and the arithmetic operators.
Arithmetic Operators
The +, -, *, / are the arithmetic operators that are available in SQL. You can use arithmetic operators in any
clause of a SQL statement (except the FROM clause). Note: With the DATE and TIMESTAMP data types, you
can use the addition and subtraction operators only.
SELECT last_name, salary, salary + 300 FROM employees;
Operator Precedence
If an arithmetic expression contains more than one operator, multiplication and division are evaluated first.
If operators in an expression are of the same priority, then evaluation is done from left to right. You can use
parentheses to force the expression that is enclosed by the parentheses to be evaluated first.
Rules of Precedence:
Multiplication and division occur before addition and subtraction.
Operators of the same priority are evaluated from left to right.
Parentheses are used to override the default precedence or to clarify the statement.
SELECT last_name, salary, 12*salary+100 FROM employees;
SELECT last_name, salary, 12*(salary+100) FROM employees;
Use parentheses to reinforce the standard order of precedence and to improve clarity.
Defining a Null Value
If a row lacks a data value for a particular column, that value is said to be null or to contain a null. Null is a
value that is unavailable, unassigned, unknown, or inapplicable. Null is not the same as zero or a blank space.
Zero is a number and blank space is a character. Columns of any data type can contain nulls. However, some
constraints (NOT NULL and PRIMARY KEY) prevent nulls from being used in the column.
SELECT last_name, job_id, salary, commission_pct FROM employees;
In the COMMISSION_PCT column in the EMPLOYEES table, notice that only a sales manager or sales
representative can earn a commission. Other employees are not entitled to earn commissions. A null
represents that fact.
SELECT last_name AS name, commission_pct comm FROM employees;
Defining a Column Alias
When displaying the result of a query, SQL Developer normally uses the name of the selected column as the
column heading. This heading may not be descriptive and, therefore, may be difficult to understand. You can
change a column heading by using a column alias. Specify the alias after the column in the SELECT list using
blank space as a separator. By default, alias headings appear in uppercase. If the alias contains spaces or
special characters (such as # or $), or if it is case-sensitive, enclose the alias in double quotation marks (" ").
SELECT last_name AS name, commission_pct comm FROM employees;
SELECT last_name "Name", salary*12 "Annual Salary" FROM employees;
Concatenation Operator
You can link columns to other columns, arithmetic expressions, or constant values to create a character
expression by using the concatenation operator (||). Columns on either side of the operator are combined
to make a single output column.
SELECT last_name||job_id AS "Employees" FROM employees;
© [email protected] RDBMS Oracle / Page 34 of 125
RDBMS using Oracle
Literal Character Strings
A literal is a character, a number, or a date that is included in the SELECT list. It is not a column name or a
column alias. It is printed for each row returned. Literal strings of free-format text can be included in the
query result and are treated the same as a column in the SELECT list. Date and character literals must be
enclosed within single quotation marks (' '); number literals need not be enclosed in a similar manner.
SELECT last_name ||' is a '||job_id AS "Employee Details" FROM employees;
SELECT last_name ||': 1 Month salary = '||salary Monthly FROM employees;
SELECT department_name || ' Department' || q'['s Manager Id: ]' || manager_id
AS "Department and Manager" FROM departments;
Duplicate Rows
Unless you indicate otherwise, SQL displays the results of a query without eliminating the duplicate rows. To
eliminate duplicate rows in the result, include the DISTINCT keyword in the SELECT clause immediately after
the SELECT keyword. You can specify multiple columns after the DISTINCT qualifier. The DISTINCT qualifier
affects all the selected columns, and the result is every distinct combination of the columns.
SELECT DISTINCT department_id FROM employees;
Restricting and Sorting Data
When retrieving data from the database, you may need to do the following:
• Restrict the rows of data that are displayed.
• Specify the order in which the rows are displayed.
• Use ampersand substitution to restrict and sort output at run time.
This method of restriction is the basis of the WHERE clause in SQL. You can restrict the rows that are
returned from the query by using the WHERE clause. The 'WHERE' clause contains a condition that must met
and it directly follows the 'FROM' clause. If the condition is true, the row meeting the condition is returned.
The 'WHERE' clause can compare values in columns, literal, arithmetic expressions, or functions etc. It
consists of three elements:
Column name Comparison condition Column name, constant, or list of values
A condition specifies a combination of one or more expressions and logical (Boolean) operators, and returns
a value of TRUE, FALSE, or UNKNOWN.
SELECT employee_id, last_name, job_id, department_id FROM employees WHERE department_id =
90 ;
SELECT last_name, job_id, department_id FROM employees WHERE last_name = 'Whalen' ;
SELECT last_name FROM employees WHERE hire_date = '17-FEB-96' ;
Here is a list of common operators used for comparison aka Comparison Operators. Comparison operators
are used in conditions that compare one expression to another value or expression. They are used in the
WHERE clause.

Operator Purpose
= Equality Check
<> / != / ^= In Equality Check
< Less Than
<= Less Than or Equal to
> Greater Than
>= Greater Than or Equal to
Between … and … Between two values (inclusive)
Not Between … and … Not Between two values (exclusive)
In Check member in list
Not In Check member not in list
Is Null Check is a null value

© [email protected] RDBMS Oracle / Page 35 of 125


RDBMS using Oracle
Is Not Null Check is not a null value
Like Match a Character Pattern
Not Like Doesn't match a Character Pattern

Few examples:
SELECT * FROM employees WHERE salary = 3000 ;
SELECT * FROM employees WHERE salary != 3000 ;
SELECT * FROM employees WHERE first_name='Julia' ;
SELECT last_name, salary FROM employees WHERE salary <= 3000 ;
SELECT last_name, salary FROM employees WHERE salary BETWEEN 2500 AND 3500 ;
SELECT last_name, salary FROM employees WHERE salary NOT BETWEEN 2500 AND 3500 ;
SELECT last_name FROM employees WHERE last_name BETWEEN 'King' AND 'Smith';
SELECT employee_id, last_name, salary, manager_id FROM employees
WHERE manager_id IN (100, 101, 201) ;
SELECT employee_id, manager_id, department_id FROM employees WHERE
last_name IN ('Hartstein', 'Vargas');
SELECT last_name, manager_id FROM employees WHERE manager_id IS NULL ;
Pattern Matching Using the LIKE Operator
You may not always know the exact value to search for. You can select rows that match a character pattern
by using the LIKE operator. The character pattern–matching operation is referred to as a wildcard search.
Two symbols can be used to construct the search string.
SELECT first_name FROM employees WHERE first_name LIKE 'S%' ;
The SELECT statement in the above example returns the first name from the EMPLOYEES table for any
employee whose first name begins with the letter "S." Note the uppercase "S." Consequently, names
beginning with a lowercase "s" are not returned. The LIKE operator can be used as a shortcut for some
BETWEEN comparisons. The following example displays the last names and hire dates of all employees who
joined between January, 1995 and December, 1995.
SELECT last_name, hire_date FROM employees WHERE hire_date LIKE '%95';
The % and _ symbols can be used in any combination with literal characters. The example below displays the
names of all employees whose last names have the letter "o" as the second character.
SELECT last_name FROM employees WHERE last_name LIKE '_o%' ;
The following example displays the names of all employees whose last name contains only five characters as
it have only five underscores in the pattern.
SELECT last_name FROM employees WHERE last_name LIKE '_ _ _ _ _' ;
When you need to have an exact match for the actual % and _ characters, use the ESCAPE identifier. This
option specifies what the escape character is. If you want to search for strings that contain SA_, you can use
the following SQL statement:
SELECT employee_id, last_name, job_id FROM employees WHERE job_id LIKE '%SA\_%' ESCAPE '\';
Defining Conditions Using the Logical Operators
A logical condition combines the result of two component conditions to produce a single result based on
those conditions or it inverts the result of a single condition. A row is returned only if the overall result of the
condition is true. Three logical operators are available in SQL:
• AND  Returns TRUE if both component conditions are true
• OR  Returns TRUE if either component condition is true
• NOT  Returns TRUE if the condition is false
You can use several conditions in a single WHERE clause using the AND and OR operators as shown below.
SELECT employee_id, last_name, job_id, salary FROM employees
WHERE salary >= 10000 AND job_id LIKE '%MAN%' ;

© [email protected] RDBMS Oracle / Page 36 of 125


RDBMS using Oracle
In the example above only those employees who have a job title that contains the string 'MAN' and earn
10,000 or more are selected whereas in the example below any employee who has a job ID that contains the
string 'MAN' or earns 10,000 or more is selected.
SELECT employee_id, last_name, job_id, salary FROM employees
WHERE salary >= 10000 OR job_id LIKE '%MAN%' ;
Defining Conditions Using the Logical Operators
The NOT operator negates the condition. The not operator can be used as
SELECT last_name, job_id FROM employees WHERE job_id NOT IN ('IT_PROG', 'ST_CLERK',
'SA_REP') ;
SELECT last_name, job_id FROM employees WHERE job_id NOT IN ('AC_ACCOUNT', 'AD_VP')
SELECT last_name, job_id FROM employees WHERE salary NOT BETWEEN 10000 AND 15000
SELECT last_name, job_id FROM employees WHERE last_name NOT LIKE '%A%'
SELECT last_name, job_id FROM employees WHERE commission_pct IS NOT NULL
Rules of Precedence
The rules of precedence determine the order in which expressions are evaluated and calculated. The table
below lists the default order of precedence. However, you can override the default order by using
parentheses around the expressions that you want to calculate first.

Operator Precedence Operator Name


1 Arithmetic Operators
2 Concatenation Operator
3 Comparison conditions
4 IS [NOT] NULL, LIKE, [NOT] IN
5 [NOT] BETWEEN
6 Not equal to
7 NOT logical condition
8 AND logical condition
9 OR logical condition
SELECT last_name, job_id, salary FROM employees
WHERE job_id = 'SA_REP' OR job_id = 'AD_PRES' AND salary > 15000;
In this example above, there are two conditions: The first condition is that the job ID is AD_PRES and the
salary is greater than $15,000. The second condition is that the job ID is SA_REP. Therefore, the SELECT
statement reads as follows: "Select the row if an employee is a president and earns more than $15,000, or if
the employee is a sales representative."
SELECT last_name, job_id, salary FROM employees
WHERE (job_id = 'SA_REP' OR job_id = 'AD_PRES') AND salary > 15000;
Whereas In the example above, there are two conditions: The first condition is that the job ID is AD_PRES or
SA_REP. The second condition is that the salary is greater than $15,000. Therefore, the SELECT statement
reads as follows: "Select the row if an employee is a president or a sales representative, and if the employee
earns more than $15,000."
Using the ORDER BY Clause
The order of rows that are returned in a query result is undefined. The ORDER BY clause can be used to sort
the rows. However, if you use the ORDER BY clause, it must be the last clause of the SQL statement. Further,
you can specify an expression, an alias, or a column position as the sort condition.
SELECT last_name, job_id, department_id, hire_date FROM employees ORDER BY hire_date ;
To reverse the order in which the rows are displayed, specify the DESC keyword after the column name in
the ORDER BY clause. The example below sorts the result by the most recently hired employee.
SELECT last_name, job_id, department_id, hire_date FROM employees ORDER BY hire_date DESC ;
You can also use a column alias in the ORDER BY clause. The example below sorts the data by annual salary.

© [email protected] RDBMS Oracle / Page 37 of 125


RDBMS using Oracle
SELECT employee_id, last_name, salary*12 annsal FROM employees ORDER BY annsal ;
You can sort query results by specifying the numeric position of the column in the SELECT clause. The
example below sorts the result by the department_id as this column is at the third position in the SELECT
clause.
SELECT last_name, job_id, department_id, hire_date FROM employees ORDER BY 3;
You can sort query results by more than one column. The sort limit is the number of columns in the given
table. In the ORDER BY clause, specify the columns and separate the column names using commas. If you
want to reverse the order of a column, specify DESC after its name.
SELECT last_name, department_id, salary FROM employees ORDER BY department_id, salary DESC;
If the ORDER BY clause is not used, the sort order is undefined, and the Oracle server may not fetch rows in
the same order for the same query twice. Use the ORDER BY clause to display the rows in a specific order.
Use the keywords NULLS FIRST or NULLS LAST to specify whether returned rows containing null values
should appear first or last in the ordering sequence.
SELECT employee_id, last_name, commission_pct FROM employees ORDER BY commission_pct
NULLS LAST ;
The default sort order is ascending:
• Numeric values are displayed with the lowest values first (for example, 1 to 999).
• Date values are displayed with the earliest value first (for example, 01-JAN-92 before
01-JAN-95).
• Character values are displayed in the alphabetical order (for example, "A" first and "Z" last).
• Null values are displayed last for ascending sequences and first for descending sequences.
• You can also sort by a column that is not in the SELECT list.
Substitution Variables
So far, all the SQL statements were executed with predetermined columns, conditions and their values.
Suppose that you want a query that lists the employees with various jobs and not just those whose job_ID is
SA_REP. You can edit the WHERE clause to provide a different value each time you run the command, but
there is also an easier way.
By using a substitution variable in place of the exact values in the WHERE clause, you can run the same query
for different values. You can create reports that prompt users to supply their own values to restrict the range
of data returned, by using substitution variables. You can embed substitution variables in a command file or
in a single SQL statement. A variable can be thought of as a container in which values are temporarily stored.
When the statement is run, the stored value is substituted.
• You can use single-ampersand (&) substitution variables to temporarily store values.
• You can also predefine variables by using the DEFINE command. DEFINE creates and assigns a value
to a variable.
Restricted Ranges of Data: Examples
• Reporting figures only for the current quarter or specified date range
• Reporting on data relevant only to the user requesting the report
• Displaying personnel only within a given department
Other Interactive Effects
Interactive effects are not restricted to direct user interaction with the WHERE clause. The same principles
can also be used to achieve other goals, such as:
• Obtaining input values from a file rather than from a person
• Passing values from one SQL statement to another
Note: Both SQL Developer and SQL* Plus support the substitution variables and the DEFINE/UNDEFINE
commands. Though SQL Developer or SQL* Plus does not support validation checks (except for data type) on
user input.
• Use substitution variables to temporarily store values with single-ampersand (&) and double-
ampersand (&&) substitution
• Use substitution variables to supplement the following:
© [email protected] RDBMS Oracle / Page 38 of 125
RDBMS using Oracle
o WHERE conditions
o ORDER BY clauses
o Column expressions
o Table names
o Entire SELECT statements
Using the Single-Ampersand Substitution Variable
When running a report, users often want to restrict the data that is returned dynamically. SQL*Plus or SQL
Developer provides this flexibility with user variables. Use an ampersand (&) to identify each variable in your
SQL statement. However, you do not need to define the value of each variable.
Example
SELECT employee_id, last_name, salary, department_id FROM
employees WHERE employee_id = &employee_num ;
The example above creates a substitution variable for an employee number. When the statement is
executed, SQL prompts the user for an employee number and then displays the employee number, last
name, salary, and department number for that employee. With the single ampersand, the user is prompted
every time the command is executed if the variable does not exist. While execution in SQL *Plus it looks alike

Consider the example below:


SELECT last_name, department_id, salary*12 FROM employees WHERE job_id = '&job_title' ;
In a WHERE clause, date and character values must be enclosed with single quotation marks. The same rule
applies to the substitution variables. Enclose the variable with single quotation marks within the SQL
statement itself.
The example above shows a query to retrieve the employee names, department numbers, and annual
salaries of all employees based on the job title value of the SQL substitution variable.
SELECT employee_id, last_name, job_id, &column_name FROM employees
WHERE &condition ORDER BY &order_column ;
In the above example, for each substitution variable in the SELECT statement, you are prompted to enter a
value. Rather you can use the double-ampersand (&&) substitution variable if you want to reuse the variable
value without prompting the user each time. The user sees the prompt for the value only once. In the
example below, the user is asked to give the value for the variable, column_name, only once.
SELECT employee_id, last_name, job_id, &&column_name FROM employees ORDER BY
&column_name ;
The value that is supplied by the user (department_id) is used for both display and ordering of data. If you
run the query again, you will not be prompted for the value of the variable. SQL stores the value that is
supplied by using the DEFINE command; it uses it again whenever you reference the variable name. After a
user variable is in place, you need to use the UNDEFINE command to delete it:
UNDEFINE column_name
Using the DEFINE Command
The example shown creates a substitution variable for an employee number by using the DEFINE command.
At run time, this displays the employee number, name, salary, and department number for that employee.
Because the variable is created using the SQL DEFINE command, the user is not prompted to enter a value
© [email protected] RDBMS Oracle / Page 39 of 125
RDBMS using Oracle
for the employee number. Instead, the defined variable value is automatically substituted in the SELECT
statement.
DEFINE employee_num = 200
SELECT employee_id, last_name, salary FROM employees WHERE employee_id = &employee_num ;
UNDEFINE employee_num
The EMPLOYEE_NUM substitution variable is present in the session until the user undefines it or exits the
SQL session.
SQL Functions
Functions are a very powerful feature of SQL. They can be used to do the following:
• Perform calculations on data
• Modify individual data items
• Manipulate output for groups of rows
• Format dates and numbers for display
• Convert column data types
SQL functions sometimes take arguments and always return a value. There are two types of SQL functions
are used in queries
• Single-row functions  These functions operate on single rows only and return one result per row.
• Multiple-row functions  These functions can manipulate groups of rows to give one result per
group of rows.
Single-Row Functions
Single-row functions are used to manipulate data items. They accept one or more arguments and return one
value for each row that is returned by the query. An argument can be one of the following:
• User-supplied constant
• Variable value
• Column name
• Expression
There are different types of single-row functions as described below:
• Character Accept character input and can return both character and number values
• Number  Accept numeric input and return numeric values
• Date  Operate on values of the DATE data type. All date functions return a value of the DATE data
type except the MONTHS_BETWEEN function, which returns a number.
• Conversion  Convert a value from one data type to another
• General  NVL, NULLIF, COALESCE, CASE, DECODE fall under this special category.
Features of single-row functions include:
• Acting on each row that is returned in the query
• Returning one result per row
• Possibly returning a data value of a different type than the one that is referenced
• Possibly expecting one or more arguments
• Can be used in SELECT, WHERE, and ORDER BY clauses; can be nested
In the syntax:
function_name [(arg1, arg2,...)]
function_name is the name of the function
arg1, arg2 is any argument to be used by the function. This can be represented by a column name or
expression.
DUAL Table
The DUAL table is owned by the user SYS and can be accessed by all users. It contains one column, DUMMY,
and one row with the value X. The DUAL table is useful when you want to return a value only once (for

© [email protected] RDBMS Oracle / Page 40 of 125


RDBMS using Oracle
example, the value of a constant, pseudocolumn, or expression that is not derived from a table with user
data). The DUAL table is generally used for completeness of the SELECT clause syntax, because both SELECT
and FROM clauses are mandatory, and several calculations do not need to select from the actual tables.
Character Functions
Single-row character functions accept character data as input and can return both character and numeric
values. Character functions can be divided into the following:
• Case-conversion functions
• Character-manipulation functions
Case-Conversion Functions
LOWER, UPPER, and INITCAP are the three case-conversion functions.
LOWER: Converts mixed-case or uppercase character strings to lowercase
UPPER: Converts mixed-case or lowercase character strings to uppercase
INITCAP: Converts the first letter of each word to uppercase and the remaining letters to lowercase
SELECT 'The job id for '||UPPER(last_name)||' is ' ||LOWER(job_id) AS "EMPLOYEE DETAILS"
FROM employees;
SELECT INITCAP(first_name||' '||last_name) FROM employees;
SELECT employee_id, last_name, department_id FROM employees WHERE last_name = 'higgins';
The last example above might give result as '0 rows selected' as there is no row contains last_name = '
higgins' it has last_name as 'Higgns', so it is better to use
SELECT employee_id, last_name, department_id FROM employees WHERE LOWER(last_name) =
'higgins';
Note: You can use functions such as UPPER and LOWER with ampersand substitution. For example, use
UPPER('&job_title') so that the user does not have to enter the job title in a specific case.
Character-Manipulation Functions
CONCAT, SUBSTR, LENGTH, INSTR, LPAD, RPAD, and TRIM are the character-manipulation functions.
CONCAT: Joins values together (You are limited to using two parameters with CONCAT.)
SUBSTR: Extracts a string of determined length
LENGTH: Shows the length of a string as a numeric value
INSTR: Finds the numeric position of a named character
LPAD: Returns an expression left-padded to the length of n characters with a character expression
RPAD: Returns an expression right-padded to the length of n characters with a character expression
TRIM: Trims leading or trailing characters (or both) from a character string (If trim_character or trim_source
is a character literal, you must enclose it within single quotation marks.)
These functions manipulate character strings as:

Function Result
CONCAT('Hello', 'World') HelloWorld
SUBSTR('HelloWorld',1,5) Hello
LENGTH('HelloWorld') 10
INSTR('HelloWorld', 'W') 6
LPAD(salary,10,'*') *****24000
RPAD(salary, 10, '*') 24000*****
REPLACE BLACK and BLUE
('JACK and JUE','J','BL')
TRIM('H' FROM 'HelloWorld') elloWorld

© [email protected] RDBMS Oracle / Page 41 of 125


RDBMS using Oracle
SELECT employee_id, CONCAT(first_name, last_name) NAME, job_id, LENGTH (last_name),
INSTR(last_name, 'a') "Contains 'a'?" FROM employees WHERE SUBSTR(job_id, 4) = 'REP';
The example above displays employee first names and last names joined together, the length of the
employee last name, and the numeric position of the letter "a" in the employee last name for all employees
who have the string, REP, contained in the job ID starting at the fourth position of the job ID.
Modify the above command to display the data for those employees whose last names end with the letter
"n."
SELECT employee_id, CONCAT(first_name, last_name) NAME, LENGTH (last_name),
INSTR(last_name, 'a') "Contains 'a'?" FROM employees WHERE SUBSTR(last_name, -1, 1) = 'n';
Number Functions
Number functions accept numeric input and return numeric values. This section describes some of the
number functions.
Function Meaning Use O/P
ABS(n) Returns absolute value (+ve equivalent) Abs(-10) 10
CEIL(n) Returns smallest integer greater than or equal to n. Ceil(10.2) 11
FLOOR(n) Returns largest integer equal to or less than n. Floor(10.6) 10
MOD(n2,n1) Returns the remainder of n2 divided by n1. Returns n2 if n1 is 0. Mod(5,2) 1
POWER(n2,n1) Returns n2 raised to the n1 power. Power(8,2) 64
ROUND(number) Returns rounded number. Round(10.7) 11
TRUNC(number) Return truncated value of number. Trunc(10.7) 10
SQRT(n) Returns the square root of n. Sqrt(64) 8
Round Function
The ROUND function rounds the column, expression, or value to n decimal places. If the second argument is
0 or is missing, the value is rounded to zero decimal places. If the second argument is 2, the value is rounded
to two decimal places. Conversely, if the second argument is –2, the value is rounded to two decimal places
to the left (rounded to the nearest unit of 100). The ROUND function can also be used with date functions.
SELECT ROUND(45.923,2), ROUND(45.923,0), ROUND(45.923,-1) FROM DUAL;
Trunc Function
The TRUNC function truncates the column, expression, or value to n decimal places. The TRUNC function
works with arguments similar to those of the ROUND function. If the second argument is 0 or is missing, the
value is truncated to zero decimal places. If the second argument is 2, the value is truncated to two decimal
places. Conversely, if the second argument is –2, the value is truncated to two decimal places to the left. If
the second argument is –1, the value is truncated to one decimal place to the left. Like the ROUND function,
the TRUNC function can be used with date functions.
SELECT TRUNC(45.923,2), TRUNC(45.923), TRUNC(45.923,-1) FROM DUAL;
Mod Function
The MOD function finds the remainder of the first argument divided by the second argument. The example
below calculates the remainder of the salary after dividing it by 5,000 for all employees whose job ID is
SA_REP. The MOD function is often used to determine whether a value is odd or even.
SELECT last_name, salary, MOD(salary, 5000) FROM employees WHERE job_id = 'SA_REP';
Working with Dates
The Oracle database stores dates in an internal numeric format, representing the century, year, month, day,
hours, minutes, and seconds. The default display and input format for any date is DD-MON-RR. Valid Oracle
dates are between January 1, 4712 B.C., and December 31, 9999 A.D.
In the example, the HIRE_DATE column output is displayed in the default format DD-MON-RR. However,
dates are not stored in the database in this format. All the components of the date and time are stored. So,
although a HIRE_DATE such as 17-JUN-87 is displayed as day, month, and year, there is also time and century
information associated with the date. The complete data might be June 17, 1987, 5:10:43 PM.
SELECT last_name, hire_date FROM employees WHERE hire_date < '01-FEB-88';

© [email protected] RDBMS Oracle / Page 42 of 125


RDBMS using Oracle
RR Date Format
The RR date format is similar to the YY element, but you can use it to specify different centuries. Use the RR
date format element instead of YY so that the century of the return value varies according to the specified
two-digit year and the last two digits of the current year. The table below summarizes the behavior of the RR
element.
Current Year Specified Date RR Format YY Format
1995 27-OCT-95 1995 1995
1995 27-OCT-17 2017 1917
2001 27-OCT-17 2017 2017
2001 27-OCT-95 1995 2095

If the specified two-digit year is:

0–49 50–99
If two digits The return date is in The return date is in
of the 0–49 the current century the century before
current the current one
year are: The return date is in The return date is in
50–99 the century after the current century
the current one
Oracle Date Format
This data is stored internally as follows:
CENTURY YEAR MONTH DAY HOUR MINUTE SECOND
19 87 06 17 17 10 43
Centuries and the Year 2000
When a record with a date column is inserted into a table, the century information is picked up from the
SYSDATE function. However, when the date column is displayed on the screen, the century component is not
displayed (by default). The DATE data type always stores year information as a four-digit number internally:
two digits for the century and two digits for the year. For example, the Oracle database stores the year as
1987 or 2004, and not just as 87 or 04.
Obtaining System Date
SYSDATE is a date function that returns the current database server date and time. You can use SYSDATE just
as you would use any other column name. For example, you can display the current date by selecting
SYSDATE from dual table.
SELECT sysdate FROM dual;
Arithmetic with Dates
Because the database stores dates as numbers, you can perform calculations using arithmetic operators
such as addition and subtraction. You can add and subtract number constants as well as dates. You can
perform the following operations:
SELECT last_name, (SYSDATE-hire_date)/7 AS WEEKS FROM employees WHERE department_id =
90;
SELECT employee_id, hire_date, MONTHS_BETWEEN (SYSDATE, hire_date) TENURE,
ADD_MONTHS (hire_date, 6) REVIEW, NEXT_DAY (hire_date, 'FRIDAY'), LAST_DAY(hire_date)
FROM employees WHERE MONTHS_BETWEEN (SYSDATE, hire_date) < 100;
Using Round and trunc
SELECT employee_id,hire_date, ROUND(hire_date, 'MONTH'), TRUNC(hire_date, 'MONTH') FROM
employees;

© [email protected] RDBMS Oracle / Page 43 of 125


RDBMS using Oracle
Function Result
MONTHS_BETWEEN Number of months between two dates
ADD_MONTHS Add calendar months to date
NEXT_DAY Next day of the date specified
LAST_DAY Last day of the month

ROUND Round date


TRUNC Truncate date

Conversion Functions
In some cases, the Oracle server receives data of one data type where it expects data of a different data
type. When this happens, the Oracle server can automatically convert the data to the expected data type.
This data type conversion can be done implicitly by the Oracle server or explicitly by the user.
Explicit data type conversions are done by using the conversion functions. Conversion functions convert a
value from one data type to another. Generally, the form of the function names follows the convention data
type TO data type. The first data type is the input data type and the second data type is the output.
TO_CHAR (character): This function converts NCHAR, NVARCHAR2, CLOB, or NCLOB data to the database
character set. The value returned is always VARCHAR2. When you use this function to convert a character
LOB into the database character set, if the LOB value to be converted is larger than the target type, then the
database returns an error.
SELECT TO_CHAR('01110') FROM DUAL;
TO_CHAR (datetime): converts a datetime or interval value of DATE, TIMESTAMP, TIMESTAMP WITH TIME
ZONE, or TIMESTAMP WITH LOCAL TIME ZONE datatype to a value of VARCHAR2 datatype in the format
specified by the date format fmt. If you omit fmt, then date is converted to a VARCHAR2.
SELECT TO_CHAR(sysdate, 'DD-MON-YYYY HH24:MI:SSxFF') FROM DUAL;
TO_CHAR (number): converts n to a value of VARCHAR2 datatype, using the optional number format fmt.
The value n can be of type NUMBER, BINARY_FLOAT, or BINARY_DOUBLE. If you omit fmt, then n is
converted to a VARCHAR2 value exactly long enough to hold its significant digits.
SELECT TO_CHAR('01110' + 1) FROM dual;
TO_DATE: converts char of CHAR, VARCHAR2, NCHAR, or NVARCHAR2 datatype to a value of DATE datatype.
SELECT TO_DATE('January 15, 1989, 11:00 A.M.', 'Month dd, YYYY, HH:MI A.M.',
'NLS_DATE_LANGUAGE = American') FROM DUAL;
SELECT TO_DATE('January 15, 1989, 11:00 A.M.','Month dd, YYYY, HH:MI A.M.',
'NLS_DATE_LANGUAGE = American') FROM DUAL;
SELECT last_name, hire_date FROM employees WHERE
hire_date = TO_DATE('May 24, 1999', 'fxMonth DD, YYYY');
TO_NUMBER: converts expr to a value of NUMBER datatype. The expr can be a BINARY_DOUBLE value or a
value of CHAR, VARCHAR2, NCHAR, or NVARCHAR2 datatype containing a number in the format specified by
the optional format model fmt.
SELECT TO_NUMBER('-AusDollars100','L9G999D99', ' NLS_NUMERIC_CHARACTERS = '',.''
NLS_CURRENCY = ''AusDollars'' ') "Amount" FROM DUAL;
Date & Time Formats
TO_CHAR converts a datetime data type to a value of VARCHAR2 data type in the format specified by the
format_model. A format model is a character literal that describes the format of datetime stored in a
character string. For example, the datetime format model for the string '11-Nov-1999' is 'DD-Mon-YYYY'. You
can use the TO_CHAR function to convert a date from its default format to the one that you specify.
Note :
• The format model must be enclosed with single quotation marks and is case-sensitive.

© [email protected] RDBMS Oracle / Page 44 of 125


RDBMS using Oracle
• The format model can include any valid date format element. But be sure to separate the date value
from the format model with a comma.
• The names of days and months in the output are automatically padded with blanks.
• To remove padded blanks or to suppress leading zeros, use the fill mode fm element.
Format Model Result
YYYY Full year in numbers
Q Quarter of year (1, 2, 3, 4; January - March = 1).
YEAR / SYEAR Year, spelled out; S prefixes BC dates with a minus sign (-).
Month Name of month.
Mon First three-letter abbreviated name of the month
MM Month (01-12; January = 01).
RM Roman Numeral Month (I-XII; January = I).
DDD Day of the year ( 1-366)
DD Day of the month ( 1-31)
D Day of the week ( 1-7 Sunday = 1)
Dy Three-letter abbreviation of the day of the week
Day Full name of the day of the week
DDTH Date number with st, nd, rd and th suffixes 1 as 1st and 5 as 5th
DDSP Spell the date number 01 as ONE and 25 as Twenty Five
DDSPTH Number suffixes spell out numbers as 01 as First and 25 as Twenty Fifth
HH / HH12 Hour of day (1-12) from 12hrs clock.
HH24 Hour of day (0-23) from 24 hrs clock.
MI Minute Number (0-59).
SS Second (0-59).
SSSSS Seconds past midnight (0-86399).
AM / A.M. / Meridian indicator with or without periods.
PM / P.M.
FM Returns a value with no leading or trailing blanks.
Examples:
SELECT last_name, TO_CHAR(hire_date, 'DD Month YYYY') AS HIREDATE FROM employees;
Modify the example to display the dates in a format that appears as "Seventeenth of June 1987 12:00:00
AM."
SELECT last_name, TO_CHAR(hire_date, 'Ddspth "of" Month YYYY HH:MI:SS AM') HIREDATE
FROM employees;
In comparison to the above example try and see the output difference using fm in formats.
1. SELECT last_name, TO_CHAR(hire_date, 'fmDdspth "of" Month YYYY fmHH:MI:SS AM')
HIREDATE FROM employees;
2. SELECT TO_CHAR(SYSDATE, 'fmDDTH')||' of '||TO_CHAR (SYSDATE, 'fmMonth')||',
'||TO_CHAR(SYSDATE, 'YYYY') "Ides" FROM DUAL;
3. SELECT TO_CHAR(SYSDATE, 'fmDay')||'''s Special' "Menu" FROM DUAL;
4. SELECT last_name employee, TO_CHAR(hire_date,'fmMonth DD, YYYY') hiredate FROM
employees WHERE department_id = 20;
Number Formats
When working with number values, such as character strings, you should convert those numbers to the
character data type using the TO_CHAR function, which translates a value of NUMBER data type to
VARCHAR2 data type. This technique is especially useful with concatenation.
© [email protected] RDBMS Oracle / Page 45 of 125
RDBMS using Oracle
Element Result
9 Represents a number
0 Forces a zero to be displayed
$ Places a floating dollar sign
L Uses the floating local currency symbol
. Prints a decimal point
, Prints a comma as a thousands indicator

More Examples
SELECT TO_CHAR(salary, '$99,999.00') SALARY FROM employees WHERE last_name = 'Ernst';
SELECT last_name employee, TO_CHAR(salary, '$99,990.99') FROM employees WHERE
department_id = 80;
SELECT last_name, TO_CHAR(hire_date, 'DD-Mon-YYYY') FROM employees WHERE hire_date <
TO_DATE('01-Jan-90','DD-Mon-RR');
Nesting Functions
Single-row functions can be nested to any depth. Nested functions are evaluated from the innermost level to
the outermost level. Some examples follow to show you the flexibility of these functions.
displays the last names of employees in department 60. The evaluation of the SQL statement involves three
steps:
1. The inner function retrieves the first eight characters of the last name.
Result1 = SUBSTR (LAST_NAME, 1, 8)
2. The outer function concatenates the result with _US.
Result2 = CONCAT(Result1, '_US')
3. The outermost function converts the results to uppercase.
The entire expression becomes the column heading because no column alias was given. Let's look at the
command.
SELECT last_name, UPPER(CONCAT(SUBSTR (LAST_NAME, 1, 8), '_US')) FROM employees
WHERE department_id = 60;
The example below will display the date of the next Friday that is six months from the hire date. The
resulting date should appear as Friday, August 13th, 1999. Order the results by hire date.
SELECT TO_CHAR(NEXT_DAY(ADD_MONTHS(hire_date, 6), 'FRIDAY'), 'fmDay, Month ddth, YYYY')
"Next 6 Month Review" FROM employees ORDER BY hire_date;
NVL Function
To convert a null value to an actual value, use the NVL function. You can use the NVL function to convert any
data type, but the return value is always the same as the data type of first expression. NVL Conversions for
Various Data types such as date, character, and number. Data types must match:
SELECT NVL(commission_pct,0) FROM employees;
SELECT NVL(hire_date,'01-JAN-97') FROM employees;
SELECT NVL(job_id,'No Job Yet') FROM employees;
SELECT last_name, salary, NVL(commission_pct, 0), (salary*12) + (salary*12*NVL(commission_pct,
0)) AN_SAL FROM employees;
Using the NVL2 Function
The NVL2 function examines the first expression. If the first expression is not null, then the NVL2 function
returns the second expression. If the first expression is null, then the third expression is returned.
SELECT last_name, salary, commission_pct, NVL2(commission_pct, 'SAL+COMM', 'SAL') income
FROM employees WHERE department_id IN (50, 80);

© [email protected] RDBMS Oracle / Page 46 of 125


RDBMS using Oracle
Using the NULLIF Function
The NULLIF function compares two expressions. If they are equal, the function returns a null. If they are not
equal, the function returns the first expression. However, you cannot specify the literal NULL for the first
expression.
SELECT first_name, LENGTH(first_name) "expr1", last_name, LENGTH(last_name) "expr2",
NULLIF(LENGTH(first_name), LENGTH(last_name)) result FROM employees;
Using the COALESCE Function
The COALESCE function returns the first non-null expression in the list. If the first expression is not null, the
COALESCE function returns that expression; otherwise, it does a COALESCE of the remaining expressions. The
advantage of the COALESCE function over the NVL function is that the COALESCE function can take multiple
alternate values.
SELECT last_name, employee_id, COALESCE(TO_CHAR(commission_pct),TO_CHAR(manager_id),
'No commission and no manager') FROM employees;
In the example above if the manager_id value is not null, it is displayed. If the manager_id value is null, then
the commission_pct is displayed. If the manager_id and commission_pct values are null, then "No
commission and no manager" is displayed. TO_CHAR function is applied so that all expressions are of the
same data type.
Write query for the employees who do not get any commission, your organization wants to give a salary
increment of 2,000 and for employees who get commission, the query should compute the new salary that is
equal to the existing salary added to the commission amount.
SELECT last_name, salary, commission_pct, COALESCE((salary+(commission_pct*salary)),
salary+2000, salary) "New Salary" FROM employees;
Conditional Expressions
The two methods that are used to implement conditional processing (IF-THEN-ELSE logic) in a SQL statement
are the CASE expression and the DECODE function. The CASE expression complies with the ANSI SQL. The
DECODE function is specific to Oracle syntax.
Syntax of Case Expression:
CASE expr WHEN comparison_expr1 THEN return_expr1
[WHEN comparison_expr2 THEN return_expr2
WHEN comparison_exprn THEN return_exprn
ELSE else_expr]
END
Example1:
SELECT last_name, job_id, salary,
CASE job_id WHEN 'IT_PROG' THEN 1.10*salary
WHEN 'ST_CLERK' THEN 1.15*salary
WHEN 'SA_REP' THEN 1.20*salary
ELSE salary END "REVISED_SALARY"
FROM employees;
Example1:
SELECT last_name,salary,
(CASE WHEN salary<5000 THEN 'Low'
WHEN salary<10000 THEN 'Medium'
WHEN salary<20000 THEN 'Good'
ELSE 'Excellent'
END) qualified_salary
FROM employees;
DECODE Function

© [email protected] RDBMS Oracle / Page 47 of 125


RDBMS using Oracle
The DECODE function decodes an expression in a way similar to the IF-THEN-ELSE logic that is used in various
languages. The DECODE function decodes expression after comparing it to each search value. If the
expression is the same as search, result is returned. If the default value is omitted, a null value is returned
where a search value does not match any of the result values.
Syntax of decode expression:
DECODE(col|expression, search1, result1 [, search2, result2,...,][, default]);
Example:
SELECT last_name, job_id, salary,
DECODE(job_id, 'IT_PROG', 1.10*salary,
'ST_CLERK', 1.15*salary,
'SA_REP', 1.20*salary,
salary)
REVISED_SALARY
FROM employees;
There is another example using the DECODE function. In this example, you determine the tax rate for each
employee in department 80 based on the monthly salary. The tax rates are as follows:
Monthly Salary Range Tax Rate
0.00–1,999.99 00%
2,000.00–3,999.99 09%
4,000.00–5,999.99 20%
6,000.00–7,999.99 30%
8,000.00–9,999.99 40%
10,000.00–11,999.99 42%
12,200.00–13,999.99 44%
14,000.00 or greater 45%
SELECT last_name, salary,
DECODE (TRUNC(salary/2000, 0),
0, 0.00,
1, 0.09,
2, 0.20,
3, 0.30,
4, 0.40,
5, 0.42,
6, 0.44,
0.45) TAX_RATE
FROM employees
WHERE department_id = 80;
Using the Group Functions
Unlike single-row functions, group functions operate on sets of rows to give one result per group. These sets
may comprise the entire table or the table split into groups. Each of the functions accepts an argument. The
following table identifies the options that you can use in the syntax:
Function Purpose
SUM It returns the sum of values of expr.
AVG It returns average value of expression.
COUNT It returns the number of rows returned by the query.
MAX It returns maximum value of expr.
MIN It returns minimum value of expr.

© [email protected] RDBMS Oracle / Page 48 of 125


RDBMS using Oracle
STDDEV It returns the sample standard deviation of expr, a set of numbers.
VARIANCE It returns the variance of expr.
Examples:
SELECT AVG(salary) "Average" FROM employees;
SELECT COUNT(*) "Total" FROM employees;
SELECT COUNT(commission_pct) "Count" FROM employees;
SELECT COUNT(DISTINCT manager_id) "Managers" FROM employees;
SELECT MAX(salary) "Maximum" FROM employees;
SELECT MIN(hire_date) "Earliest" FROM employees;
SELECT STDDEV(salary) "Deviation" FROM employees;
SELECT SUM(salary) "Total" FROM employees;
SELECT VARIANCE(salary) "Variance" FROM employees;
SELECT AVG(salary), MAX(salary), MIN(salary), SUM(salary) FROM employees WHERE job_id LIKE
'%REP%';
Group Functions and Null Values
All group functions ignore null values in the column. However, the NVL function forces group functions to
include null values.
SELECT AVG(commission_pct) FROM employees;
In the example above the average is calculated based on only those rows in the table in which a valid value is
stored in the COMMISSION_PCT column. The average is calculated as the total commission that is paid to all
employees divided by the number of employees receiving a commission (four).
SELECT AVG(NVL(commission_pct, 0)) FROM employees;
In the example above average is calculated based on all rows in the table, regardless of whether null values
are stored in the COMMISSION_PCT column. The average is calculated as the total commission that is paid to
all employees divided by the total number of employees in the company (20).
Creating Groups of Data: GROUP BY Clause Syntax
You can use the GROUP BY clause to divide the rows in a table into groups. You can then use the group
functions to return summary information for each group. If you include a group function in a SELECT clause,
you cannot select individual results as well, unless the individual column appears in the GROUP BY clause.
You receive an error message if you fail to include the column list in the GROUP BY clause. Using a WHERE
clause, you can exclude rows before dividing them into groups. You must include the columns in the GROUP
BY clause. You cannot use a column alias in the GROUP BY clause.
Syntax :
SELECT column, group_function(column)
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[ORDER BY column];
Example:
SELECT department_id, AVG(salary) FROM employees GROUP BY department_id ;
SELECT AVG(salary) FROM employees GROUP BY department_id ;
SELECT department_id, AVG(salary) FROM employees GROUP BY department_id ORDER BY
AVG(salary);
Grouping by More than One Column
Sometimes you need to see results for groups within groups. The following example shows a report that
displays the total salary that is paid to each job title in each department.
SELECT department_id dept_id, job_id, SUM(salary) FROM employees GROUP BY department_id,
job_id
ORDER BY department_id;
© [email protected] RDBMS Oracle / Page 49 of 125
RDBMS using Oracle
The EMPLOYEES table is grouped first by the department number and then by the job title within that
grouping.
SELECT department_id, count(last_name) FROM employees GROUP BY department_id;
SELECT department_id, job_id, COUNT(last_name) FROM employees GROUP BY department_id,
job_id;
Having in Group by
SELECT department_id, AVG(salary) FROM employees WHERE AVG(salary) > 8000 GROUP BY
department_id;
The WHERE clause cannot be used to restrict groups. The SELECT statement in the above example results in
an error because it uses the WHERE clause to restrict the display of the average salaries of those
departments that have an average salary greater than 8,000. However, you can correct the error in the
example by using the HAVING clause to restrict groups as:
SELECT department_id, AVG(salary) FROM employees GROUP BY department_id HAVING
AVG(salary) > 8000;
When you use the HAVING clause, the Oracle server restricts groups as follows:
1. Rows are grouped.
2. The group function is applied.
3. Groups matching the HAVING clause are displayed.
SELECT department_id, MAX(salary) FROM employees GROUP BY department_id HAVING
MAX(salary)>10000 ;
SELECT job_id, SUM(salary) PAYROLL FROM employees WHERE job_id NOT LIKE '%REP%'
GROUP BY job_id HAVING SUM(salary) > 13000 ORDER BY SUM(salary);
Nesting Group Functions
Group functions can be nested to a depth of two functions. The example calculates the average salary for
each department_id and then displays the maximum average salary. Note that GROUP BY clause is
mandatory when nesting group functions.
SELECT MAX(AVG(salary)) FROM employees GROUP BY department_id;
Obtaining Data from Multiple Tables or JOINS
Sometimes you need to use data from more than one table. In the diagram below, the report displays data
from two separate tables:
• Employee IDs exist in the EMPLOYEES table.
• Department IDs exist in both the EMPLOYEES and DEPARTMENTS tables.
• Department names exist in the DEPARTMENTS table.
To produce the report, you need to link the EMPLOYEES and DEPARTMENTS tables, and access data from
both of them.

© [email protected] RDBMS Oracle / Page 50 of 125


RDBMS using Oracle
Joins
To join tables, you can use a join syntax that is compliant with the SQL:1999 standard. Before the Oracle9i
release, the join syntax was different from the American National Standards Institute (ANSI) standards. The
SQL:1999–compliant join syntax does not offer any performance benefits over the Oracle-proprietary join
syntax that existed in the prior releases. Joins that are compliant with the SQL:1999 standard include the
following:
Natural joins:
• USING clause
• ON clause
Self Join
Nonequi Joins
Outer joins:
• LEFT OUTER JOIN
• RIGHT OUTER JOIN
• FULL OUTER JOIN
Cartesian Product
• CROSS JOIN

Syntax:
SELECT table1.column, table2.column
FROM table1 [NATURAL JOIN table2]
| [JOIN table2 USING (column_name)]
| [JOIN table2 ON (table1.column_name = table2.column_name)]
| [LEFT|RIGHT|FULL OUTER JOIN table2 ON (table1.column_name = table2.column_name)]
| [CROSS JOIN table2];
In the syntax:
• table1.column denotes the table and the column from which data is retrieved
• NATURAL JOIN joins two tables based on the same column name
• JOIN table2 USING column_name performs an equijoin based on the column name
• JOIN table2 ON table1.column_name = table2.column_name performs an equijoin based on the
condition in the ON clause
• LEFT/RIGHT/FULL OUTER is used to perform outer joins
• CROSS JOIN returns a Cartesian product from the two tables
Qualifying Ambiguous Column Names
When joining two or more tables, you need to qualify the names of the columns with the table name to
avoid ambiguity. Without the table prefixes, the DEPARTMENT_ID column in the SELECT list could be from
either the DEPARTMENTS table or the EMPLOYEES table. It is necessary to add the table prefix to execute
your query. If there are no common column names between the two tables, there is no need to qualify the
columns. However, using the table prefix improves performance, because you tell the Oracle server exactly
where to find the columns.
However, qualifying column names with table names can be time consuming, particularly if the table names
are lengthy. Instead, you can use table aliases. Just as a column alias gives a column another name, a table
alias gives a table another name. Table aliases help to keep SQL code smaller, therefore using less memory.
The table name is specified in full, followed by a space and then the table alias. For example, the EMPLOYEES
table can be given an alias of e, and the DEPARTMENTS table an alias of d etc.
Guidelines
• Table aliases can be up to 30 characters in length, but shorter aliases are better than longer ones.
• If a table alias is used for a particular table name in the FROM clause, then that table alias must be
substituted for the table name throughout the SELECT statement.
© [email protected] RDBMS Oracle / Page 51 of 125
RDBMS using Oracle
• Table aliases should be meaningful.
• The table alias is valid for only the current SELECT statement.
Retrieving Records with Natural Joins
In the example below the LOCATIONS table is joined to the DEPARTMENT table by the LOCATION_ID column,
which is the only column of the same name in both tables. If other common columns were present, the join
would have used them all.
SELECT department_id, department_name, location_id, city
FROM departments NATURAL JOIN locations ;
Natural Joins with a WHERE Clause
Additional restrictions on a natural join are implemented by using a WHERE clause. The following example
limits the rows of output to those with a department ID equal to 20 or 50:
SELECT department_id, department_name, location_id, city FROM departments
NATURAL JOIN locations WHERE department_id IN (20, 50);
Retrieving Records with the USING Clause
In the example below the DEPARTMENT_ID columns in the EMPLOYEES and DEPARTMENTS tables are joined
and thus the LOCATION_ID of the department where an employee works is shown.
SELECT employee_id, last_name, location_id, department_id FROM employees
JOIN departments USING (department_id) ;
When joining with the USING clause, you cannot qualify a column that is used in the USING clause itself.
Furthermore, if that column is used anywhere in the SQL statement, you cannot alias it. For example, in the
query mentioned, you should not alias the location_id column in the WHERE clause because the column is
used in the USING clause. The columns that are referenced in the USING clause should not have a qualifier
(table name or alias) anywhere in the SQL statement. For example, the following statement is valid:
SELECT l.city, d.department_name FROM locations l JOIN departments d USING (location_id)
WHERE location_id = 1400;
Because, other columns that are common in both the tables, but not used in the USING clause, must be
prefixed with a table alias otherwise you get the "column ambiguously defined" error. In the following
statement, manager_id is present in both the employees and departments table and if manager_id is not
prefixed with a table alias, it gives a "column ambiguously defined" error.
The following statement is valid:
SELECT first_name, d.department_name, d.manager_id FROM employees e JOIN departments d
USING (department_id) WHERE department_id = 50;
Retrieving Records with the ON Clause
In the following example, the DEPARTMENT_ID columns in the EMPLOYEES and DEPARTMENTS table are
joined using the ON clause. Wherever a department ID in the EMPLOYEES table equals a department ID in
the DEPARTMENTS table, the row is returned. The table alias is necessary to qualify the matching
column_names.
SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id
FROM employees e JOIN departments d ON (e.department_id = d.department_id);
You can also use the ON clause to join columns that have different names. The parenthesis around the
joined columns as in the example, (e.department_id = d.department_id) is optional. So, even ON
e.department_id = d.department_id will work.
Creating Three-Way Joins with the ON Clause
A three-way join is a join of three tables. In SQL:1999–compliant syntax, joins are performed from left to
right. So, the first join to be performed is EMPLOYEES JOIN DEPARTMENTS. The first join condition can
reference columns in EMPLOYEES and DEPARTMENTS but cannot reference columns in LOCATIONS. The
second join condition can reference columns from all three tables.
SELECT employee_id, city, department_name FROM employees e JOIN departments d
ON d.department_id = e.department_id JOIN locations l ON d.location_id = l.location_id;
The result obtained through codes in the example above can also be accomplished with the USING clause:
© [email protected] RDBMS Oracle / Page 52 of 125
RDBMS using Oracle
SELECT e.employee_id, l.city, d.department_name FROM employees e
JOIN departments d USING (department_id) JOIN locations l USING (location_id);
Applying Additional Conditions to a Join
You can apply additional conditions to the join. The example shown below performs a join on the
EMPLOYEES and DEPARTMENTS tables and, in addition, displays only employees who have a manager ID of
149. To add additional conditions to the ON clause, you can add AND clauses. Alternatively, you can use a
WHERE clause to apply additional conditions.
SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id FROM
employees e
JOIN departments d ON (e.department_id = d.department_id) AND e.manager_id = 149 ;
Or you can use
SELECT e.employee_id, e.last_name, e.department_id, d.department_id, d.location_id FROM
employees e
JOIN departments d ON (e.department_id = d.department_id) WHERE e.manager_id = 149 ;
Joining a Table to Itself or Self Join
Sometimes you need to join a table to itself. To find the name of each employee's manager, you need to join
the EMPLOYEES table to itself, or perform a self-join. For example, to find the name of Lorentz's manager,
you need to:
• Find Lorentz in the EMPLOYEES table by looking at the LAST_NAME column
• Find the manager number for Lorentz by looking at the MANAGER_ID column. Lorentz's manager
number is 103.
• Find the name of the manager with EMPLOYEE_ID 103 by looking at the LAST_NAME column.
Hunold's employee number is 103, so Hunold is Lorentz's manager.
In this process, you look in the table twice. The first time you look in the table to find Lorentz in the
LAST_NAME column and the MANAGER_ID value of 103. The second time you look in the EMPLOYEE_ID
column to find 103 and the LAST_NAME column to find Hunold.
SELECT worker.last_name emp, manager.last_name mgr FROM employees worker
JOIN employees manager ON (worker.manager_id = manager.employee_id);
Nonequijoins
A nonequijoin is a join condition containing something other than an equality operator. The relationship
between the EMPLOYEES table and the JOB_GRADES table is an example of a nonequijoin. The SALARY
column in the EMPLOYEES table ranges between the values in the LOWEST_SAL and HIGHEST_SAL columns
of the JOB_GRADES table. Hence, each employee can be graded based on their salary. The relationship is
obtained using an operator other than the equality (=) operator.
SELECT e.last_name, e.salary, j.grade_level FROM employees e JOIN job_grades j
ON e.salary BETWEEN j.lowest_sal AND j.highest_sal;
Returning Records with No Direct Match with Outer Joins
If a row does not satisfy a join condition, the row does not appear in the query result. For example, in the
equijoin condition of EMPLOYEES and DEPARTMENTS tables, department ID 190 does not appear because
there are no employees with that department ID recorded in the EMPLOYEES table. Therefore, instead of
seeing 20 employees in the result set, you see 19 records. To return the department record that does not
have any employees, you can use an outer join.
INNER Versus OUTER Joins
Joining tables with the NATURAL JOIN, USING, or ON clauses results in an inner join. Any unmatched rows
are not displayed in the output. To return the unmatched rows, you can use an outer join. An outer join
returns all rows that satisfy the join condition and also returns some or all of those rows from one table for
which no rows from the other table satisfy the join condition.
There are three types of outer joins:
• LEFT OUTER
SELECT e.last_name, e.department_id, d.department_name FROM employees e

© [email protected] RDBMS Oracle / Page 53 of 125


RDBMS using Oracle
LEFT OUTER JOIN departments d ON (e.department_id = d.department_id) ;
This query retrieves all rows in the EMPLOYEES table, which is the left table, even if there is no
match in the DEPARTMENTS table.
• RIGHT OUTER
SELECT e.last_name, e.department_id, d.department_name FROM employees e
RIGHT OUTER JOIN departments d ON (e.department_id = d.department_id) ;
This query retrieves all rows in the DEPARTMENTS table, which is the right table, even if there is no
match in the EMPLOYEES table.
• FULL OUTER
SELECT e.last_name, d.department_id, d.department_name FROM employees e
FULL OUTER JOIN departments d ON (e.department_id = d.department_id) ;
This query retrieves all rows in the EMPLOYEES table, even if there is no match in the DEPARTMENTS
table. It also retrieves all rows in the DEPARTMENTS table, even if there is no match in the
EMPLOYEES table.
Cartesian Products
When a join condition is invalid or omitted completely, the result is a Cartesian product, in which all
combinations of rows are displayed. All rows in the first table are joined to all rows in the second table.
A Cartesian product tends to generate a large number of rows and the result is rarely useful. You should,
therefore, always include a valid join condition unless you have a specific need to combine all rows from all
tables.
However, Cartesian products are useful for some tests when you need to generate a large number of rows to
simulate a reasonable amount of data.
SELECT last_name, department_name FROM employees CROSS JOIN departments ;
A Cartesian product is generated if a join condition is omitted. The example above displays the employee last
name and the department name from the EMPLOYEES and DEPARTMENTS tables. Because no join condition
was specified, all rows (20 rows) from the EMPLOYEES table are joined with all rows (8 rows) in the
DEPARTMENTS table, thereby generating 160 rows in the output.
Using a Subquery to Solve a Problem
Suppose you want to write a query to find out who earns a salary greater than Abel's salary. To solve this
problem, you need two queries: one to find how much Abel earns, and a second query to find who earns
more than that amount. You can solve this problem by combining the two queries, placing one query inside
the other query.
The inner query (or subquery) returns a value that is used by the outer query (or main query). Using a
subquery is equivalent to performing two sequential queries and using the result of the first query as the
search value in the second query.
Syntax:
SELECT select_list FROM table WHERE expr operator (SELECT select_list FROM table);
In the syntax:
operator includes a comparison condition such as >, =, or IN
A subquery is a SELECT statement that is embedded in the clause of another SELECT statement. You can
build powerful statements out of simple ones by using subqueries. They can be very useful when you need
to select rows from a table with a condition that depends on the data in the table itself. You can place the
subquery in a number of SQL clauses, including the following:
• WHERE clause
• HAVING clause
• FROM clause
Comparison conditions fall into two classes: single-row operators (>, =, >=, <, <>, <=) and multiple-row
operators (IN, ANY, ALL). The subquery is often referred to as a nested SELECT, sub-SELECT, or inner SELECT
statement. The subquery generally executes first, and its output is used to complete the query condition for
the main (or outer) query.

© [email protected] RDBMS Oracle / Page 54 of 125


RDBMS using Oracle
Guidelines for Using Subqueries
• A subquery must be enclosed in parentheses.
• Place the subquery on the right side of the comparison condition for readability. However, the
subquery can appear on either side of the comparison operator.
• Two classes of comparison conditions are used in subqueries: single-row operators and
multiple-row operators.
SELECT last_name, salary FROM employees WHERE salary >
(SELECT salary FROM employees WHERE last_name = 'Abel');
In the example above, the inner query determines the salary of employee Abel. The outer query takes the
result of the inner query and uses this result to display all the employees who earn more than employee
Abel.
Types of Subqueries
Single-row subqueries: Queries that return only one row from the inner SELECT statement
Multiple-row subqueries: Queries that return more than one row from the inner SELECT statement
There are also multiple-column subqueries, which are queries that return more than one column from the
inner SELECT statement.
Single-Row Subqueries
A single-row subquery is one that returns one row from the inner SELECT statement. This type of subquery
uses a single-row operator.
Example:
Display the employees whose job ID is the same as that of employee 141:
SELECT last_name, job_id FROM employees WHERE job_id =
(SELECT job_id FROM employees WHERE employee_id = 141);
A SELECT statement can be considered as a query block. The example below displays employees who do the
same job as "Taylor," but earn more salary than him. The example consists of three query blocks: the outer
query and two inner queries. The inner query blocks are executed first, producing the query results SA_REP
and 8600, respectively. The outer query block is then processed and uses the values that were returned by
the inner queries to complete its search conditions.
Both inner queries return single values (SA_REP and 8600, respectively), so this SQL statement is called a
single-row subquery. The outer and inner queries can get data from different tables.
SELECT last_name, job_id, salary FROM employees WHERE job_id =
(SELECT job_id FROM employees WHERE last_name = 'Taylor') AND
salary > (SELECT salary FROM employees WHERE last_name = 'Taylor');
Using Group Functions in a Subquery
You can display data from a main query by using a group function in a subquery to return a single row. The
subquery is in parentheses and is placed after the comparison condition. The example given below displays
the employee last name, job ID, and salary of all employees whose salary is equal to the minimum salary.
The MIN group function returns a single value (2500) to the outer query.
SELECT last_name, job_id, salary FROM employees WHERE salary =
(SELECT MIN(salary) FROM employees);
The HAVING Clause with Subqueries
You can use subqueries not only in the WHERE clause, but also in the HAVING clause. The Oracle server
executes the subquery and the results are returned into the HAVING clause of the main query.
SELECT department_id, MIN(salary) FROM employees
GROUP BY department_id HAVING MIN(salary) >
(SELECT MIN(salary) FROM employees WHERE department_id = 50);
The above example of SQL statement displays all the departments that have a minimum salary greater than
that of department 50. Let's take another example to Find the job with the lowest average salary.
SELECT job_id, AVG(salary) FROM employees

© [email protected] RDBMS Oracle / Page 55 of 125


RDBMS using Oracle
GROUP BY job_id HAVING AVG(salary) =
(SELECT MIN(AVG(salary)) FROM employees GROUP BY job_id);
No Rows Returned by the Inner Query
A common problem with subqueries occurs when no rows are returned by the inner query.
SELECT last_name, job_id FROM employees WHERE job_id =
(SELECT job_id FROM employees WHERE last_name = 'Haas');
In the SQL statement in the example, the subquery contains a WHERE clause. Presumably, the intention is to
find the employee whose name is Haas. The statement is correct, but selects no rows when executed.
Because, there is no employee named Haas. So the subquery returns no rows. The outer query takes the
results of the subquery (null) and uses these results in its WHERE clause. The outer query finds no employee
with a job ID equal to null, and so returns no rows. If a job existed with a value of null, the row is not
returned because comparison of two null values yields a null; therefore, the WHERE condition is not true.
Multiple-Row Subqueries
Subqueries that return more than one row are called multiple-row subqueries. You use a multiple-row
operator, instead of a single-row operator, with a multiple-row subquery. The multiple-row operator expects
one or more values:
SELECT last_name, salary, department_id FROM employees WHERE salary IN
(SELECT MIN(salary) FROM employees GROUP BY department_id);
Example:
Find the employees who earn the same salary as the minimum salary for each department. The inner query
is executed first, producing a query result. The main query block is then processed and uses the values that
were returned by the inner query to complete its search condition. In fact, the main query appears to the
Oracle server as follows:
SELECT last_name, salary, department_id FROM employees
WHERE salary IN (2500, 4200, 4400, 6000, 7000, 8300, 8600, 17000);
Using the ANY Operator in Multiple-Row Subqueries
The ANY operator (and its synonym, the SOME operator) compares a value to each value returned by a
subquery. <ANY means less than the maximum. >ANY means more than the minimum. =ANY is equivalent to
IN.
The example displays employees who are not IT programmers and whose salary is less than that of any IT
programmer. The maximum salary that a programmer earns is 9,000.
SELECT employee_id, last_name, job_id, salary FROM employees WHERE
salary < ANY (SELECT salary FROM employees WHERE job_id = 'IT_PROG') AND job_id <>
'IT_PROG';
Using the ALL Operator in Multiple-Row Subqueries
The ALL operator compares a value to every value returned by a subquery. The example displays employees
whose salary is less than the salary of all employees with a job ID of IT_PROG and whose job is not IT_PROG.
>ALL means more than the maximum and <ALL means less than the minimum. The NOT operator can be
used with IN, ANY, and ALL operators.
SELECT employee_id, last_name, job_id, salary FROM employees WHERE
salary < ALL (SELECT salary FROM employees WHERE job_id = 'IT_PROG') AND job_id <>
'IT_PROG';
Set Operators
Set operators combine the results of two or more component queries into one result. Queries containing set
operators are called compound queries. All set operators have equal precedence. If a SQL statement
contains multiple set operators, the Oracle server evaluates them from left (top) to right (bottom)—if no
parentheses explicitly specify another order. You should use parentheses to specify the order of evaluation
explicitly in queries that use the INTERSECT operator with other set operators.

© [email protected] RDBMS Oracle / Page 56 of 125


RDBMS using Oracle
Set Operator Guidelines
• The expressions in the SELECT lists of the queries must match in number and data type. Queries that
use UNION, UNION ALL, INTERSECT, and MINUS operators in their WHERE clause must have the
same number and data type of columns in their SELECT list. The data type of the columns in SELECT
list of the queries in the compound query may not be exactly the same. The column in second query
must be in the same data type group (such as numeric or character) as the corresponding column in
the first query.
• Set operators can be used in subqueries.
• You should use parentheses to specify the order of evaluation in queries that use the INTERSECT
operator with other set operators. This ensures compliance with emerging SQL standards that will
give the INTERSECT operator greater precedence than the other set operators.
UNION Operator
The UNION operator returns all rows that are selected by either query. Use the UNION operator to return all
rows from multiple tables and eliminate any duplicate rows. Following points must be considered:
• The number of columns being selected must be the same.
• The data types of the columns being selected must be in the same data type group (such as numeric
or character).
• The names of the columns need not be identical.
• UNION operates over all of the columns being selected.
• NULL values are not ignored during duplicate checking.
• By default, the output is sorted in ascending order of the columns of the SELECT clause.
SELECT employee_id, job_id FROM employees
UNION
SELECT employee_id, job_id FROM job_history;
UNION ALL Operator
Use the UNION ALL operator to return all rows from multiple queries. The guidelines for UNION and UNION
ALL are the same, with the following two exceptions that pertain to UNION ALL: Unlike UNION, duplicate
rows are not eliminated and the output is not sorted by default.
SELECT employee_id, job_id, department_id FROM employees
UNION ALL
SELECT employee_id, job_id, department_id FROM job_history
ORDER BY employee_id;
INTERSECT Operator
Use the INTERSECT operator to return all rows that are common to multiple queries. The number of
columns and the data types of the columns being selected by the SELECT statements in the queries must be
identical in all the SELECT statements used in the query. The names of the columns, however, need not be
identical. Reversing the order of the intersected tables does not alter the result. INTERSECT does not ignore
NULL values.
Display the employee IDs and job IDs of those employees who currently have a job title that is the same as
their previous one (that is, they changed jobs but have now gone back to doing the same job they did
previously).
SELECT employee_id, job_id FROM employees
INTERSECT
SELECT employee_id, job_id FROM job_history;
MINUS Operator
Use the MINUS operator to return all distinct rows selected by the first query, but not present in the second
query result set (the first SELECT statement MINUS the second SELECT statement). The number of columns
must be the same and the data types of the columns being selected by the SELECT statements in the queries
must belong to the same data type group in all the SELECT statements used in the query. The names of the
columns, however, need not be identical.
© [email protected] RDBMS Oracle / Page 57 of 125
RDBMS using Oracle
Display the employee IDs of those employees who have not changed their jobs even once.
SELECT employee_id FROM employees
MINUS
SELECT employee_id FROM job_history;
Matching the SELECT Statements
SELECT location_id, department_name "Department", TO_CHAR(NULL) "Warehouse location"
FROM departments
UNION
SELECT location_id, TO_CHAR(NULL) "Department", state_province FROM locations;
Because the expressions in the SELECT lists of the queries must match in number, you can use the dummy
columns and the data type conversion functions to comply with this rule. In the example, the name,
Warehouse location, is given as the dummy column heading. The TO_CHAR function is used in the first query
to match the VARCHAR2 data type of the state_province column that is retrieved by the second query.
Similarly, the TO_CHAR function in the second query is used to match the VARCHAR2 data type of the
department_name column that is retrieved by the first query.
Using the ORDER BY Clause in Set Operations
The ORDER BY clause can be used only once in a compound query. If used, the ORDER BY clause must be
placed at the end of the query. The ORDER BY clause accepts the column name or an alias. By default, the
output is sorted in ascending order in the first column of the first SELECT query.
The ORDER BY clause does not recognize the column names of the second SELECT query. To avoid confusion
over column names, it is a common practice to ORDER BY column positions. For example, in the following
statement, the output will be shown in ascending order of the job_id.
SELECT employee_id, job_id,salary FROM employees
UNION
SELECT employee_id, job_id,0 FROM job_history
ORDER BY 2;
If you omit the ORDER BY, then by default the output will be sorted in the ascending order of employee_id.
You cannot use the columns from the second query to sort the output.
Using the UNION operator, display the employee ID, job ID, and salary of all employees.
SELECT employee_id, job_id,salary
FROM employees
UNION
SELECT employee_id, job_id,0
FROM job_history;
Miscellaneous Issues
Inserting Rows with Null Values
Be sure that you can use null values in the targeted column by verifying the Null status with the DESCRIBE
command. The Oracle server automatically enforces all data types, data ranges, and data integrity
constraints. Any column that is not listed explicitly obtains a null value in the new row. Common errors that
can occur during user input are checked in the following order:
• Mandatory value missing for a NOT NULL column
• Duplicate value violating any unique or primary key constraint
• Any value violating a CHECK constraint
• Referential integrity maintained for foreign key constraint
• Data type mismatches or values too wide to fit in column
Use of the column list is recommended as it makes the INSERT statement more readable and reliable, or less
prone to mistakes. Somehow you can insert rows with null values in two methods shown below.
Implicit method: Omit the column from the column list.
INSERT INTO departments (department_id, department_name) VALUES (30, 'Purchasing');
© [email protected] RDBMS Oracle / Page 58 of 125
RDBMS using Oracle
Explicit method: Specify the NULL keyword in the VALUES clause.
INSERT INTO departments VALUES (100, 'Finance', NULL, NULL);
Inserting Special Values
You can use functions to enter special values in your table. The example records information for employee
Popp in the EMPLOYEES table. It supplies the current date and time in the HIRE_DATE column. It uses the
SYSDATE function that returns the current date and time of the database server. You may also use the
CURRENT_DATE function to get the current date in the session time zone. You can also use the USER
function when inserting rows in a table. The USER function records the current username.
INSERT INTO employees (employee_id, first_name, last_name, email, phone_number, hire_date,
job_id, salary, commission_pct, manager_id, department_id) VALUES (113, 'Louis', 'Popp',
'LPOPP', '515.124.4567', SYSDATE, 'AC_ACCOUNT', 6900, NULL, 205, 110);
Inserting Specific Date and Time Values
The DD-MON-RR format is generally used to insert a date value. With the RR format, the system provides the
correct century automatically. You may also supply the date value in the DD-MON-YYYY format. This is
recommended because it clearly specifies the century and does not depend on the internal RR format logic
of specifying the correct century. If a date must be entered in a format other than the default format (for
example, with another century or a specific time), you must use the TO_DATE function. The example records
information for employee Raphealy in the EMPLOYEES table. It sets the HIRE_DATE column to be February 3,
1999.
INSERT INTO employees VALUES (114, 'Den', 'Raphealy', 'DRAPHEAL', '515.127.4561',
TO_DATE('FEB 3, 1999', 'MON DD, YYYY'), 'SA_REP', 11000, 0.2, 100, 60);
Copying Rows from Another Table
You can use the INSERT statement to add rows to a table where the values are derived from existing tables.
In the example, for the INSERT INTO statement to work, you must have already created the sales_reps table
using the CREATE TABLE statement.
INSERT INTO sales_reps(id, name, salary, commission_pct)
SELECT employee_id, last_name, salary, commission_pct FROM employees WHERE job_id LIKE
'%REP%';
In place of the VALUES clause, you use a subquery. The number of columns and their data types in the
column list of the INSERT clause must match the number of values and their data types in the subquery. Zero
or more rows are added depending on the number of rows returned by the subquery. To create a copy of
the rows of a table, use SELECT * in the subquery:
INSERT INTO copy_emp SELECT * FROM employees;
UPDATE Statement
You can modify the existing values in a table by using the UPDATE statement. In general, use the primary key
column in the WHERE clause to identify a single row for update. Using other columns can unexpectedly
cause several rows to be updated. For example, identifying a single row in the EMPLOYEES table by name is
dangerous, because more than one employee may have the same name. The UPDATE statement modifies
the values of a specific row or rows if the WHERE clause is specified. The example shows the transfer of
employee 113 (Popp) to department 50. If you omit the WHERE clause, values for all the rows in the table
are modified.
UPDATE employees
SET department_id = 50
WHERE employee_id = 113;
Examine the updated rows in the COPY_EMP table.
SELECT last_name, department_id FROM copy_emp;
Consider the following use of Update command.
UPDATE copy_emp SET department_id = 110;
Values for all the rows in the table are modified if you omit the WHERE clause. Specify SET column_name=
NULL to update a column value to NULL.

© [email protected] RDBMS Oracle / Page 59 of 125


RDBMS using Oracle
For example, an employee who was a SA_REP has now changed his job to an IT_PROG. Therefore, his JOB_ID
needs to be updated and the commission field needs to be set to NULL.
UPDATE employees
SET job_id = 'IT_PROG', commission_pct = NULL
WHERE employee_id = 114;
Updating Two Columns with a Subquery
You can update multiple columns in the SET clause of an UPDATE statement by writing multiple subqueries.
Update employee 113's job and salary to match those of employee 205.
UPDATE employees SET job_id = (SELECT job_id FROM employees WHERE employee_id =
205),
salary = (SELECT salary FROM employees WHERE employee_id = 205)
WHERE employee_id = 113;
The example above can also be written as follows:
UPDATE employees SET (job_id, salary) = (SELECT job_id, salary FROM employees
WHERE employee_id = 205) WHERE employee_id = 113;
Updating Rows Based on Another Table
You can use the subqueries in the UPDATE statements to update values in a table. The example given below,
updates the COPY_EMP table based on the values from the EMPLOYEES table. It changes the department
number of all employees with employee 200's job ID to employee 100's current department number.
UPDATE copy_emp SET department_id = (SELECT department_id FROM employees
WHERE employee_id = 100)
WHERE job_id= (SELECT job_id FROM employees WHERE employee_id = 200);
Removing a Row from a Table
The Contracting department has been removed from the DEPARTMENTS table (assuming no constraints on
the DEPARTMENTS table are violated), as shown in the figure.
Departments Table: Departments Table after delete:

Deleting Rows from a Table


You can delete specific rows by specifying the WHERE clause in the DELETE statement. The first example in
the diagram deletes the Accounting department from the DEPARTMENTS table. You can confirm the delete
operation by displaying the deleted rows using the SELECT statement.
SELECT * FROM departments WHERE department_name = 'Finance';
However, if you omit the WHERE clause, all rows in the table are deleted.
DELETE FROM copy_emp;
The example above will delete all rows from the COPY_EMP table, because no WHERE clause was specified.
Here are few more examples.
DELETE FROM employees WHERE employee_id = 114;
DELETE FROM departments WHERE department_id IN (30, 40);
Deleting Rows Based on Another Table
You can use the subqueries to delete rows from a table based on values from another table. The example
deletes all employees in a department where the department name contains the string Admin. The subquery
searches the DEPARTMENTS table to find the department number based on the department name
© [email protected] RDBMS Oracle / Page 60 of 125
RDBMS using Oracle
containing the string Public. The subquery then feeds the department number to the main query, which
deletes rows of data from the EMPLOYEES table based on this department number.
DELETE FROM employees WHERE department_id =
(SELECT department_id FROM departments WHERE department_name LIKE '%Public%');
TRUNCATE Statement
A more efficient method of emptying a table is by using the TRUNCATE statement. You can use the
TRUNCATE statement to quickly remove all rows from a table. Removing rows with the TRUNCATE statement
is faster than removing them with the DELETE statement for the following reasons:
• The TRUNCATE statement is a data definition language (DDL) statement and generates no rollback
information.
• Truncating a table does not fire the delete triggers of the table.
If the table is the parent of a referential integrity constraint, you cannot truncate the table. You need to
disable the constraint before issuing the TRUNCATE statement. For example:
TRUNCATE TABLE copy_emp;
Database Transactions
The Oracle server ensures data consistency based on transactions. Transactions give you more flexibility and
control when changing data and they ensure data consistency in the event of user process failure or system
failure. A database transaction consists of one of the following:
• DML statements that constitute one consistent change to the data
• One DDL statement
• One data control language (DCL) statement
For example, a transfer of funds between two accounts should include the debit in one account and the
credit to another account of the same amount. Both actions should either fail or succeed together; the credit
should not be committed without the debit.
Transaction Types: Start and End
When does a database transaction start and end? A transaction begins when the first DML statement is
encountered and ends when one of the following occurs:
• A COMMIT or ROLLBACK statement is issued.
• A DDL statement, such as CREATE, is issued.
• A DCL statement is issued.
• The user exits SQL Developer or SQL*Plus.
• A machine fails or the system crashes.
After one transaction ends, the next executable SQL statement automatically starts the next transaction. A
DDL statement or a DCL statement is automatically committed and therefore implicitly ends a transaction.
The Advantages of COMMIT and ROLLBACK Statements is, With the COMMIT and ROLLBACK statements, you
have control over making changes to the data permanent. With COMMIT and ROLLBACK statements, you
can:
• Ensure data consistency
• Preview data changes before making changes permanent
• Group logically-related operations
Rolling Back Changes to a Marker
You can create a marker in the current transaction by using the SAVEPOINT statement, which divides the
transaction into smaller sections. You can then discard pending changes up to that marker by using the
ROLLBACK TO SAVEPOINT statement. Note, if you create a second savepoint with the same name as an
earlier savepoint, the earlier savepoint is deleted.
Create a marker in the current transaction by using the SAVEPOINT statement. Roll back to that marker by
using the ROLLBACK TO SAVEPOINT statement.
UPDATE...
SAVEPOINT update_done;

© [email protected] RDBMS Oracle / Page 61 of 125


RDBMS using Oracle
INSERT...
ROLLBACK TO update_done;
In SQL*Plus, the AUTOCOMMIT command can be toggled ON or OFF. If set to ON, each individual DML
statement is committed as soon as it is executed. You cannot roll back the changes. If set to OFF, the
COMMIT statement can still be issued explicitly. Also, the COMMIT statement is issued when a DDL
statement is issued or when you exit SQL*Plus.
Committing Data
Remove departments 290 and 300 in the DEPARTMENTS table and update a row in the EMPLOYEES table.
Save the data change.
DELETE FROM departments WHERE department_id IN (290, 300);
UPDATE employees SET department_id = 80 WHERE employee_id = 206;
COMMIT;
In the example below, a row is deleted from the EMPLOYEES table and a new row is inserted into the
DEPARTMENTS table. The changes are saved by issuing the COMMIT statement.
DELETE FROM employees WHERE employee_id = 99999;
INSERT INTO departments VALUES (290, 'Corporate Tax', NULL, 1700);
COMMIT;
Using Rollback
Discard all pending changes by using the ROLLBACK statement, which results in the following:
• Data changes are undone.
• The previous state of the data is restored.
• Locks on the affected rows are released.
Try with following example and see the state of rows.
DELETE FROM copy_emp;
While attempting to remove a record from the copy_emp table, you may accidentally empty the table.
However, you can correct the mistake as:
ROLLBACK ;
It's important while performing SQL queries, reissue a proper statement, and make the data change
permanent using commit; statement.
FOR UPDATE Clause in a SELECT Statement
When you issue a SELECT statement against the database to query some records, no locks are placed on the
selected rows. In general, this is required because the number of records locked at any given time is (by
default) kept to the absolute minimum: only those records that have been changed but not yet committed
are locked. Even then, others will be able to read those records as they appeared before the change (the
"before image" of the data). There are times, however, when you may want to lock a set of records even
before you change them in your program. Oracle offers the FOR UPDATE clause of the SELECT statement to
perform this locking.
SELECT employee_id, salary, commission_pct, job_id FROM employees
WHERE job_id = 'SA_REP' FOR UPDATE ORDER BY employee_id;
When you issue a SELECT...FOR UPDATE statement, the relational database management system (RDBMS)
automatically obtains exclusive row-level locks on all the rows identified by the SELECT statement, thereby
holding the records "for your changes only." No one else will be able to change any of these records until
you perform a ROLLBACK or a COMMIT.
You can append the optional keyword NOWAIT to the FOR UPDATE clause to tell the Oracle server not to
wait if the table has been locked by another user. In this case, control will be returned immediately to your
program or to your SQL Developer environment so that you can perform other work, or simply wait for a
period of time before trying again. Without the NOWAIT clause, your process will block until the table is
available, when the locks are released by the other user through the issue of a COMMIT or a ROLLBACK
command.
FOR UPDATE Clause: Examples

© [email protected] RDBMS Oracle / Page 62 of 125


RDBMS using Oracle
SELECT e.employee_id, e.salary, e.commission_pct FROM employees e
JOIN departments d USING (department_id) WHERE job_id = 'ST_CLERK' AND location_id = 1500
FOR UPDATE ORDER BY e.employee_id;
In the example above the statement locks rows in the EMPLOYEES table with JOB_ID set to ST_CLERK and
LOCATION_ID set to 1500, and locks rows in the DEPARTMENTS table with departments in LOCATION_ID set
as 1500.
You can use the FOR UPDATE OF column_name to qualify the column that you intend to change. The OF list
of the FOR UPDATE clause does not restrict you to changing only those columns of the selected rows. Locks
are still placed on all rows; if you simply state FOR UPDATE in the query and do not include one or more
columns after the OF keyword, the database will lock all identified rows across all the tables listed in the
FROM clause.
The following statement locks only those rows in the EMPLOYEES table with ST_CLERK located in
LOCATION_ID 1500. No rows are locked in the DEPARTMENTS table:
SELECT e.employee_id, e.salary, e.commission_pct FROM employees e JOIN departments d
USING (department_id) WHERE job_id = 'ST_CLERK' AND location_id = 1500
FOR UPDATE OF e.salary ORDER BY e.employee_id;
Referencing Another User's Tables
A schema is a collection of logical structures of data or schema objects. A schema is owned by a database
user and has the same name as that user. Each user owns a single schema. Schema objects can be created
and manipulated with SQL and include tables, views, synonyms, sequences, stored procedures, indexes,
clusters, and database links.
If a table does not belong to the user, the owner's name must be prefixed to the table. For example, if there
are schemas named USERA and USERB, and both have an EMPLOYEES table, then if USERA wants to access
the EMPLOYEES table that belongs to USERB, USERA must prefix the table name with the schema name:
SELECT * FROM userb.employees;
If USERB wants to access the EMPLOYEES table that is owned by USERA, USERB must prefix the table name
with the schema name:
SELECT * FROM usera.employees;
DEFAULT Option
When you define a table, you can specify that a column should be given a default value by using the
DEFAULT option. This option prevents null values from entering the columns when a row is inserted without
a value for the column. The default value can be a literal, an expression, or a SQL function (such as SYSDATE
or USER), but the value cannot be the name of another column or a pseudocolumn (such as NEXTVAL or
CURRVAL). The default expression must match the data type of the column. Create a table:
CREATE TABLE hire_dates (id NUMBER(8), hire_date DATE DEFAULT SYSDATE);
Now consider the following examples:
INSERT INTO hire_dates values(45, NULL);
The above statement will insert the null value rather than the default value.
INSERT INTO hire_dates(id) values(35);
The above statement will insert SYSDATE for the HIRE_DATE column.
More about FOREIGN KEY Constraint
The FOREIGN KEY (or referential integrity) constraint designates a column or a combination of columns as a
foreign key and establishes a relationship with a primary key or a unique key in the same table or a different
table.
In the schema used in our example, DEPARTMENT_ID has been defined as the foreign key in the EMPLOYEES
table (dependent or child table); it references the DEPARTMENT_ID column of the DEPARTMENTS table (the
referenced or parent table). The foreign key can also be defined at the column level, provided that the
constraint is based on a single column. The syntax differs in that the keywords FOREIGN KEY do not appear.
For example:
CREATE TABLE employees
(
© [email protected] RDBMS Oracle / Page 63 of 125
RDBMS using Oracle
employee_id NUMBER(6) CONSTRAINT emp_emp_id_pk PRIMARY KEY,
first_name VARCHAR2(20),
last_name VARCHAR2(25) NOT NULL,
email VARCHAR2(25) NOT NULL CONSTRAINT emp_email_uk UNIQUE,
phone_number VARCHAR2(20),
hire_date DATE NOT NULL,
job_id VARCHAR2(10) NOT NULL CONSTRAINT emp_job_fk REFERENCES jobs (job_id),
salary NUMBER(8,2) CONSTRAINT emp_salary_min CHECK (salary > 0),
commission_pct NUMBER(2,2),
manager_id NUMBER(6) CONSTRAINT emp_manager_fk REFERENCES
employees(employee_id),
department_id NUMBER(4) CONSTRAINT emp_dept_fk REFERENCES
departments(department_id)
);
FOREIGN KEY constraints can be defined at the column or table constraint level. A composite foreign key
must be created by using the table-level definition. The example defines a FOREIGN KEY constraint on the
DEPARTMENT_ID column of the EMPLOYEES table, using table-level syntax. The name of the constraint is
EMP_DEPT_FK.
CREATE TABLE employees
(
employee_id NUMBER(6),
last_name VARCHAR2(25) NOT NULL,
...

department_id NUMBER(4),
CONSTRAINT emp_dept_fk FOREIGN KEY (department_id)
REFERENCES departments(department_id),
CONSTRAINT emp_email_uk UNIQUE(email)
);
FOREIGN KEY Constraint: Keywords
The foreign key is defined in the child table and the table containing the referenced column is the parent
table. The foreign key is defined using a combination of the following keywords:
• FOREIGN KEY is used to define the column in the child table at the table-constraint level.
• REFERENCES identifies the table and the column in the parent table.
• ON DELETE CASCADE indicates that when a row in the parent table is deleted, the dependent rows
in the child table are also deleted.
• ON DELETE SET NULL indicates that when a row in the parent table is deleted, the foreign key values
are set to null.
The default behavior is called the restrict rule, which disallows the update or deletion of referenced data.
Without the ON DELETE CASCADE or the ON DELETE SET NULL options, the row in the parent table cannot be
deleted if it is referenced in the child table.
Creating a Table Using a Subquery
A second method for creating a table is to apply the AS subquery clause, which both creates the table and
inserts rows returned from the subquery.
CREATE TABLE table [(column, column...)] AS subquery;
The table is created with the specified column names, and the rows retrieved by the SELECT statement are
inserted into the table. The column definition can contain only the column name and default value. If column
specifications are given, the number of columns must equal the number of columns in the subquery SELECT

© [email protected] RDBMS Oracle / Page 64 of 125


RDBMS using Oracle
list. If no column specifications are given, the column names of the table are the same as the column names
in the subquery.
The column data type definitions and the NOT NULL constraint are passed to the new table. Note that only
the explicit NOT NULL constraint will be inherited. The PRIMARY KEY column will not pass the NOT NULL
feature to the new column. Any other constraint rules are not passed to the new table. However, you can
add constraints in the column definition.
CREATE TABLE dept80 AS SELECT employee_id, last_name, salary*12 ANNSAL, hire_date
FROM employees WHERE department_id = 80;
This command creates a table named DEPT80, which contains details of all the employees working in
department 80. Notice that the data for the DEPT80 table comes from the EMPLOYEES table. However, be
sure to provide a column alias when selecting an expression. The expression SALARY*12 is given the alias
ANNSAL. Without the alias, the error is generated.
ALTER TABLE Statement
After you create a table, you may need to change the table structure for any of the following reasons:
• You omitted a column.
• Your column definition or its name needs to be changed.
• You need to remove columns.
• You want to put the table into the read-only mode
Use the ALTER TABLE statement to:
• Add a new column
• Modify an existing column definition
• Define a default value for the new column
• Drop a column
• Rename a column
• Change table to read-only status
Read-Only Tables
With Oracle Database 11g, you can specify READ ONLY to place a table in the read-only mode. When the
table is in the READ-ONLY mode, you cannot issue any DML statements that affect the table or any SELECT ...
FOR UPDATE statements. You can issue DDL statements as long as they do not modify any data in the table.
Operations on indexes associated with the table are allowed when the table is in the READ ONLY mode.
ALTER TABLE employees READ ONLY;
Specify READ/WRITE to return a read-only table to the read/write mode.
ALTER TABLE employees READ WRITE;
You can drop a table that is in the READ ONLY mode. The DROP command is executed only in the data
dictionary, so access to the table contents is not required. The space used by the table will not be reclaimed
until the tablespace is made read/write again, and then the required changes can be made to the block
segment headers, and so on.
Dropping a Table
The DROP TABLE statement moves a table to the recycle bin or removes the table and all its data from the
database entirely. Unless you specify the PURGE clause, the DROP TABLE statement does not result in space
being released back to the tablespace for use by other objects, and the space continues to count towards
the user's space quota. Dropping a table invalidates the dependent objects and removes object privileges on
the table. When you drop a table, the database loses all the data in the table and all the indexes associated
with it.
DROP TABLE dept80;
Controlling User Access
In a multiple-user environment, you want to maintain security of the database access and use. With Oracle
server database security, you can do the following:
• Control database access.
• Give access to specific objects in the database.
© [email protected] RDBMS Oracle / Page 65 of 125
RDBMS using Oracle
• Confirm given and received privileges with the Oracle data dictionary.
Database security can be classified into two categories:
• System security
• Data security.
System security covers access and use of the database at the system level, such as the username and
password, the disk space allocated to users, and the system operations that users can perform.
Database security covers access and use of the database objects and the actions that those users can
perform on the objects.
Privileges
A privilege is the right to execute particular SQL statements. The database administrator (DBA) is a high-level
user with the ability to create users and grant users access to the database and its objects. Users require
system privileges to gain access to the database and object privileges to manipulate the content of the
objects in the database. Users can also be given the privilege to grant additional privileges to other users or
to roles, which are named groups of related privileges.
Schemas
A schema is a collection of objects such as tables, views, and sequences. The schema is owned by a database
user and has the same name as that user.
A system privilege is the right to perform a particular action, or to perform an action on any schema objects
of a particular type. An object privilege provides the user the ability to perform a particular action on a
specific schema object.
More than 100 privileges are available. The database administrator has high-level system privileges for tasks
such as:
• Creating new users
• Removing users
• Removing tables
• Backing up tables
Creating Users
The DBA creates the user by executing the CREATE USER statement. The user does not have any privileges at
this point. The DBA can then grant privileges to that user. These privileges determine what the user can do
at the database level.
Syntax for creating a user
CREATE USER user
IDENTIFIED BY password;
In the syntax:
user Is the name of the user to be created
Password Specifies that the user must log in with this password
Example
CREATE USER demo
IDENTIFIED BY demo;
Note: Starting Oracle Database 11g, passwords are case sensitive. Uppercase and lowercase characters are
different characters when used in a password.
User System Privileges
After the DBA creates a user, the DBA can assign privileges to that user.
GRANT privilege [, privilege...]
TO user [, user| role, PUBLIC...];
In the syntax:
privilege Is the system privilege to be granted
user |role|PUBLIC Is the name of the user, the name of the role, or PUBLIC
(which designates that every user is granted the privilege)
© [email protected] RDBMS Oracle / Page 66 of 125
RDBMS using Oracle
Note: Current system privileges can be found in the SESSION_PRIVS dictionary view. Data dictionary is a
collection of tables and views created and maintained by the Oracle server. They contain information about
the database.
An application developer, for example, may have the following system privileges:
CREATE SESSION
CREATE TABLE
CREATE SEQUENCE
CREATE VIEW
CREATE PROCEDURE
Granting System Privileges
The DBA uses the GRANT statement to allocate system privileges to the user. After the user has been
granted the privileges, the user can immediately use those privileges.
In the example given below,, the demo user has been assigned the privileges to create sessions, tables,
sequences, and views.
GRANT create session, create table,
create sequence, create view
TO demo;
Creating Rolls
What Is a Role?
A role is a named group of related privileges that can be granted to the user. This method makes it easier to
revoke and maintain privileges. A user can have access to several roles, and several users can be assigned
the same role. Roles are typically created for a database application.
Creating and Assigning a Role
First, the DBA must create the role.
role. Then the DBA can assign privileges to the role and assign the role to
users.
Syntax
CREATE ROLE role;
In the syntax:
role Is the name of the role to be created
After the role is created, the DBA can use the GRANT statement to assign the role to users
use as well as assign
privileges to the role.

Create a role:
CREATE ROLE manager;
Grant privileges to a role:
GRANT create table, create view TO manager;
Grant a role to users:
GRANT manager TO BELL, KOCHHAR;

© [email protected]
com DBMS Oracle / Page 67 of 125
RDBM
RDBMS using Oracle
Changing User Password
The DBA creates your user account and initializes your password. You can change your password by using
the ALTER USER statement.
ALTER USER demo IDENTIFIED BY employ;
Note: SQL*Plus has a PASSWORD command (PASSW) that can be used to change the password of a user
when the user is logged in. This command is not available in SQL Developer.
Object Privileges
An object privilege is a privilege or right to perform a particular action on a specific table, view, sequence, or
procedure. Each object has a particular set of grantable privileges. The table in the example lists the
privileges for various objects. Note that the only privileges that apply to a sequence are SELECT and ALTER.
UPDATE, REFERENCES, and INSERT can be restricted by specifying a subset of updatable columns.
Object privileges vary from object to object.
An owner has all the privileges on the object.
An owner can give specific privileges on that owner's object.
Syntax
GRANT object_priv [(columns)] ON object TO {user|role|PUBLIC} [WITH GRANT OPTION];
A SELECT privilege can be restricted by creating a view with a subset of columns and granting the SELECT
privilege only on the view. A privilege granted on a synonym is converted to a privilege on the base table
referenced by the synonym.
Note: With the REFERENCES privilege, you can ensure that other users can create FOREIGN KEY constraints
that reference your table.
Few Examples
Grant query privileges on the EMPLOYEES table:
GRANT select ON employees TO demo;
Grant privileges to update specific columns to users and roles:
GRANT update (department_name, location_id) ON departments TO demo, manager;
Passing On Your Privileges
Give a user authority to pass along privileges:
GRANT select, insert ON departments TO demo WITH GRANT OPTION;
Allow all users on the system to query data from Alice's DEPARTMENTS table:
GRANT select ON alice.departments TO PUBLIC;
Confirming Granted Privileges
If you attempt to perform an unauthorized operation, such as deleting a row from a table for which you do
not have the DELETE privilege, the Oracle server does not permit the operation to take place. If you receive
the Oracle server error message "Table or view does not exist," then you have done either of the following:
• Named a table or view that does not exist.
• Attempted to perform an operation on a table or view for which you do not have the appropriate
privilege.
The data dictionary is organized in tables and views and contains information about the database. You can
access the data dictionary to view the privileges that you have. The table in the example describes various
data dictionary views.
Data Dictionary View Description
ROLE_SYS_PRIVS System privileges granted to roles
ROLE_TAB_PRIVS Table privileges granted to roles
USER_ROLE_PRIVS Roles accessible by the user
USER_SYS_PRIVS System privileges granted to the user
USER_TAB_PRIVS_MADE Object privileges granted on the user's
© [email protected] RDBMS Oracle / Page 68 of 125
RDBMS using Oracle
objects

USER_TAB_PRIVS_RECD Object privileges granted to the user


Object privileges granted on the
USER_COL_PRIVS_MADE
columns of the user's objects
Object privileges granted to the user
USER_COL_PRIVS_RECD
on specific columns

Note: The ALL_TAB_PRIVS_MADE dictionary view describes all the object grants made by the user or made
on the objects owned by the user.
Revoking Object Privileges
You use the REVOKE statement to revoke privileges granted to other users. Privileges granted to others
through the WITH GRANT OPTION clause are also revoked.
Syntax:
REVOKE {privilege [, privilege...]|ALL}
ON object
FROM {user[, user...]|role|PUBLIC}
[CASCADE CONSTRAINTS];
Revoke the SELECT and INSERT privileges given to the demo user on the DEPARTMENTS table.
REVOKE select, insert ON departments FROM demo;
If a user is granted a privilege with the WITH GRANT OPTION clause, that user can also grant the privilege
with the WITH GRANT OPTION clause, so that a long chain of grantees is possible, but no circular grants
(granting to a grant ancestor) are permitted. If the owner revokes a privilege from a user who granted the
privilege to other users, then the revoking cascades to all the privileges granted.
For example, if user A grants a SELECT privilege on a table to user B including the WITH GRANT OPTION
clause, user B can grant to user C the SELECT privilege with the WITH GRANT OPTION clause as well, and user
C can then grant to user D the SELECT privilege. If user A revokes privileges from user B, then the privileges
granted to users C and D are also revoked.
Database Objects
There are several other objects in a database in addition to tables such as views, sequences, indexes, and
synonyms.
• With views, you can present and hide data from the tables.
• Many applications require the use of unique numbers as primary key values. You can either build
code into the application to handle this requirement or use a sequence to generate unique numbers.
• If you want to improve the performance of data retrieval queries, you should consider creating an
index. You can also use indexes to enforce uniqueness on a column or a collection of columns.
• You can provide alternative names for objects by using synonyms.
What Is a View?
You can present logical subsets or combinations of data by creating views of tables. A view is a logical table
based on a table or another view. A view contains no data of its own, but is like a window through which
data from tables can be viewed or changed. The tables on which a view is based are called base tables. The
view is stored as a SELECT statement in the data dictionary.
Advantages of Views
• Views restrict access to the data because it displays selected columns from the table.
• Views can be used to make simple queries to retrieve the results of complicated queries. For
example, views can be used to query information from multiple tables without the user knowing
how to write a Join statement.
• Views provide data independence for ad hoc users and application programs. One view can be used
to retrieve data from several tables.
• Views provide groups of users access to data according to their particular criteria.
© [email protected] RDBMS Oracle / Page 69 of 125
RDBMS using Oracle
There are two classifications for views:
• Simple Views
• Complex Views
The basic difference is related to the DML (INSERT, UPDATE, and DELETE) operations.
A simple view is one that
• Derives data from only one table
• Contains no functions or groups of data
• Can perform DML operations through the view
A complex view is one that:
• Derives data from many tables
• Contains functions or groups of data
• Does not always allow DML operations through the view
Syntax
CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW view [(alias[, alias]...)]
AS subquery
[WITH CHECK OPTION [CONSTRAINT constraint]]
[WITH READ ONLY [CONSTRAINT constraint]];
Create the EMPVU80 view, which contains details of the employees in department 80:
CREATE VIEW empvu80 AS
SELECT employee_id, last_name, salary FROM employees
WHERE department_id = 80;
Describe the structure of the view by using the SQL*Plus DESCRIBE command:
DESCRIBE empvu80;
You can control the column names by including column aliases in the subquery.
The example below creates a view containing the employee number (EMPLOYEE_ID) with the alias
ID_NUMBER, name (LAST_NAME) with the alias NAME, and annual salary (SALARY) with the alias
ANN_SALARY for every employee in department 50.
CREATE VIEW salvu50 AS SELECT employee_id ID_NUMBER, last_name NAME,
salary*12 ANN_SALARY FROM employees WHERE department_id = 50;
Alternatively, you can use an alias after the CREATE statement and before the SELECT subquery. The number
of aliases listed must match the number of expressions selected in the subquery.
CREATE OR REPLACE VIEW salvu50 (ID_NUMBER, NAME, ANN_SALARY)
AS SELECT employee_id, last_name, salary*12 FROM employees
WHERE department_id = 50;
Retrieving Data from a View
You can retrieve data from a view as you would from any table. You can display either the contents of the
entire view or just specific rows and columns.
SELECT * FROM salvu50;
Modifying a View
With the OR REPLACE option, a view can be created even if one exists with this name already, thus replacing
the old version of the view for its owner. This means that the view can be altered without dropping,
re-creating, and regranting object privileges. When assigning column aliases in the CREATE OR REPLACE
VIEW clause, remember that the aliases are listed in the same order as the columns in the subquery.
CREATE OR REPLACE VIEW empvu80 (id_number, name, sal, department_id) AS
SELECT employee_id, first_name || ' ' || last_name, salary, department_id
FROM employees
WHERE department_id = 80;

© [email protected] RDBMS Oracle / Page 70 of 125


RDBMS using Oracle
Creating a complex view
Create a complex view that contains group functions to display values from two tables:
CREATE OR REPLACE VIEW dept_sum_vu (name, minsal, maxsal, avgsal)
AS SELECT d.department_name, MIN(e.salary), MAX(e.salary),AVG(e.salary)
FROM employees e JOIN departments d ON (e.department_id = d.department_id)
GROUP BY d.department_name;
Rules for Performing DML Operations on a View
You can perform DML operations on data through a view if those operations follow certain rules. You can
remove a row from a view unless it contains any of the following:
• Group functions
• A GROUP BY clause
• The DISTINCT keyword
• The pseudocolumn ROWNUM keyword
You cannot modify data in a view if it contains:
• Group functions
• A GROUP BY clause
• The DISTINCT keyword
• The pseudocolumn ROWNUM keyword
• Columns defined by expressions
You cannot add data through a view if the view includes:
• Group functions
• A GROUP BY clause
• The DISTINCT keyword
• The pseudocolumn ROWNUM keyword
• Columns defined by expressions
• NOT NULL columns in the base tables that are not selected by the view
You can ensure that no DML operations occur by adding the WITH READ ONLY option to your view
definition. Any attempt to perform a DML operation on any row in the view results in an Oracle server error.
CREATE OR REPLACE VIEW empvu10 (employee_number, employee_name, job_title)
AS SELECT employee_id, last_name, job_id FROM employees
WHERE department_id = 10 WITH READ ONLY ;
Removing a View
You use the DROP VIEW statement to remove a view. The statement removes the view definition from the
database. However, dropping views has no effect on the tables on which the view was based. On the other
hand, views or other applications based on the deleted views become invalid. Only the creator or a user with
the DROP ANY VIEW privilege can remove a view.
Syntax :
DROP VIEW view;
Example :
DROP VIEW empvu80;
Sequences
A sequence is a user created database object that creates integer values. You can create sequences and then
use them to generate numbers. A sequence can be shared by multiple users to generate integers. You can
define a sequence to generate unique values or to recycle and use the same numbers again.
Sequence numbers are stored and generated independent of tables. Therefore, the same sequence can be
used for multiple tables.

© [email protected] RDBMS Oracle / Page 71 of 125


RDBMS using Oracle
Syntax :
CREATE SEQUENCE sequence
[INCREMENT BY n]
[START WITH n]
[{MAXVALUE n | NOMAXVALUE}]
[{MINVALUE n | NOMINVALUE}]
[{CYCLE | NOCYCLE}]
[{CACHE n | NOCACHE}];
Example :
CREATE SEQUENCE dept_deptid_seq
INCREMENT BY 10
START WITH 120
MAXVALUE 9999
NOCACHE
NOCYCLE;
NEXTVAL and CURRVAL Pseudocolumns
After you create your sequence, it generates sequential numbers for use in your tables. Reference the
sequence values by using the NEXTVAL and CURRVAL pseudocolumns.
The NEXTVAL pseudocolumn is used to extract successive sequence numbers from a specified sequence. You
must qualify NEXTVAL with the sequence name. When you reference sequence.NEXTVAL, a new sequence
number is generated and the current sequence number is placed in CURRVAL.
The CURRVAL pseudocolumn is used to refer to a sequence number that the current user has just generated.
However, NEXTVAL must be used to generate a sequence number in the current user's session before
CURRVAL can be referenced. You must qualify CURRVAL with the sequence name. When you reference
sequence.CURRVAL, the last value returned to that user's process is displayed.
Using Sequences
Insert a new department named "Support" in location ID 2500:
INSERT INTO departments(department_id, department_name, location_id)
VALUES (dept_deptid_seq.NEXTVAL, 'Support', 2500);
View the current value for the DEPT_DEPTID_SEQ sequence:
SELECT dept_deptid_seq.CURRVAL FROM dual;
Change the increment value, maximum value, minimum value, cycle option, or cache option:
ALTER SEQUENCE dept_deptid_seq INCREMENT BY 20 MAXVALUE 999999
NOCACHE NOCYCLE;
To remove a sequence, use the DROP statement:
DROP SEQUENCE dept_deptid_seq;
Indexes
Indexes are database objects that you can create to improve the performance of some queries. Indexes can
also be created automatically by the server when you create a primary key or a unique constraint.
An index Is a schema object. It can be used by the Oracle server to speed up the retrieval of rows by using a
pointer. It can reduce disk input/output (I/O) by using a rapid path access method to locate data quickly. It is
an independent of the table that it indexes and is used and maintained automatically by the Oracle server.
You can create two types of indexes.
Unique index: The Oracle server automatically creates this index when you define a column in a table to
have a PRIMARY KEY or a UNIQUE constraint. The name of the index is the name that is given to the
constraint.

© [email protected] RDBMS Oracle / Page 72 of 125


RDBMS using Oracle
Nonunique index: This is an index that a user can create. For example, you can create the FOREIGN KEY
column index for a join in a query to improve the speed of retrieval.
You can manually create a unique index, but it is recommended that you create a unique constraint, which
implicitly creates a unique index.
Create an index on one or more columns:
CREATE [UNIQUE][BITMAP]INDEX index ON table (column[, column]...);
Improve the speed of query access to the LAST_NAME column in the EMPLOYEES table:
CREATE INDEX emp_last_name_idx ON employees(last_name);
More Is Not Always Better. Having more indexes on a table does not produce faster queries. Each DML
operation that is committed on a table with indexes means that the indexes must be updated. The more
indexes that you have associated with a table, the more effort the Oracle server must make to update all the
indexes after a DML operation.
When to Create an Index
• Therefore, you should create indexes only if:
• The column contains a wide range of values
• The column contains a large number of null values
• One or more columns are frequently used together in a WHERE clause or join condition
• The table is large and most queries are expected to retrieve less than 2% to 4% of the rows
Remember that if you want to enforce uniqueness, you should define a unique constraint in the table
definition. A unique index is then created automatically.
You cannot modify indexes. To change an index, you must drop it and then re-create it. Remove an index
definition from the data dictionary by issuing the DROP INDEX statement. To drop an index, you must be the
owner of the index or have the DROP ANY INDEX privilege.
Syntax:
DROP INDEX index;
Example:
DROP INDEX emp_last_name_idx;

Synonyms
Synonyms are database objects that enable you to call a table by another name. You can create synonyms to
give an alternative name to a table. To refer to a table that is owned by another user, you need to prefix the
table name with the name of the user who created it, followed by a period. Creating a synonym eliminates
the need to qualify the object name with the schema and provides you with an alternative name for a table,
view, sequence, procedure, or other objects. This method can be especially useful with lengthy object
names, such as views.
Syntax:
CREATE [PUBLIC] SYNONYM synonym FOR object;
Example:
CREATE SYNONYM d_sum FOR dept_sum_vu;
Drop a Synonym
DROP SYNONYM d_sum;

© [email protected] RDBMS Oracle / Page 73 of 125


RDBMS using Oracle
Oracle – PL/SQL
Procedural Structured Query Language
About PL/SQL
Stands for "Procedural Language extension to SQL". It is Oracle Corporation's standard data access language
for relational databases seamlessly integrates procedural constructs with SQL. Structured Query Language
(SQL) is the primary language used to access and modify data in relational databases. There are only a few
SQL commands, so you can easily learn and use them. Consider an example:
SELECT first_name, department_id, salary FROM employees;
The SQL statement shown above is simple and straightforward. However, if you want to alter any data that is
retrieved in a conditional manner, you soon encounter the limitations of SQL. Consider a slightly modified
problem statement: For every employee retrieved, check the department ID and the salary. Depending on
the department's performance and also the employee's salary, you may want to provide varying bonuses to
the employees.
Looking at the problem, you know that you have to execute the preceding SQL statement, collect the data,
and apply logic to the data. One solution is to write a SQL statement for each department to give bonuses to
the employees in that department. Remember that you also have to check the salary component before
deciding the bonus amount. This makes it a little complicated. You now feel that it would be much easier if
you had conditional statements. PL/SQL is designed to meet such requirements. It provides a programming
extension to the already-existing SQL.
The PL/SQL provides a block structure for executable units of code. Maintenance of code is made easier with
such a well-defined structure. Provides procedural constructs such as:
• Variables, constants, and data types
• Control structures such as conditional statements and loops
• Reusable program units that are written once and executed many times
PL/SQL defines a block structure for writing code. Maintaining and debugging the code is made easier with
such a structure. One can easily understand the flow and execution of the program unit.
PL/SQL offers modern software engineering features such as data encapsulation, exception handling,
information hiding, and object orientation. It brings state-of-the-art programming to the Oracle server and
toolset. PL/SQL provides all the procedural constructs that are available in any third-generation language
(3GL).
History and Background
The PL/SQL was developed by Oracle in the late 1980s. Originally, PL/SQL had limited capabilities, but that
changed in the early 1990s. PL/SQL provides the Oracle database with a built-in interpreted and operating
system–independent programming environment. SQL statements are natively integrated in the PL/SQL
language.
You can also call PL/SQL directly from the command-line SQL*Plus interface. Similar direct calls can be made
in your external programming language calls to the database. The Oracle 8 Database introduced object types
into the database. It moved the Oracle database from a purely relational model into an object-relational (or
extended relational) model. These types were of limited value as collections of scalar variables until they
became instantiable in Oracle 9i, Release 2. The ability to instantiate SQL object types made internal Oracle
objects compatible with C++, Java, or C# object types. PL/SQL evolved with the advent of full object-oriented
programming capabilities delivered in Oracle 9i, Release 2. PL/SQL is no longer a purely procedural language.
It is now both a procedural and object-oriented programming language.

© [email protected] RDBMS Oracle / Page 74 of 125


RDBMS using Oracle
The Oracle 11g Database also evolved PL/SQL from an interpreted language to a natively compiled language.
You may ask: "Doesn'tt that eliminate the benefit of an operating system–
system independent language?"
language? The
answer to that question is not at all. Now you can write PL/SQL once in an operating system–independent
system
form. Then, you can deploy it and let Oracle manage its native compilation.
compilation. Oracle 11g automates the
process for you on supported platforms.
Architecture

The above diagram shows the PL/SQL execution environment in the Oracle database server. A PL/SQL block
contains procedural statements and SQL statements. When you submit the PL/SQL block to the server, the
PL/SQL engine first parses the block. The PL/SQL engine identifies the procedural statements and the SQL
statements. It passes the procedural
procedural statements to the procedural statement executor and the SQL
statements to the SQL statement executor individually.
The diagram shows the PL/SQL engine within the database server. The Oracle application development tools
can also contain a PL/SQL engine.
engine. The tool passes the blocks to its local PL/SQL engine. Therefore, all
procedural statements are executed locally and only the SQL statements are executed in the database. The
engine used depends on where the PL/SQL block is being invoked from.
Benefits of PL/SQL
Integration of procedural constructs with SQL: The most important advantage of PL/SQL is the integration
of procedural constructs with SQL. SQL is a nonprocedural language. When you issue a SQL command, your
command tells the database server what to do. However, you cannot specify how to do it. PL/SQL integrates
control statements and conditional statements with SQL, giving you better control of your SQL statements
and their execution.
Improved performance: Without PL/SQL, you would not be able to logically combine SQL statements as one
unit. If you have designed an application containing forms, you may have many different forms with fields in
each form. When a form submits the data, you
may have to execute a number of SQL
statements. SQL statements nts are sent to the
database one at a time. This results in many
network trips and one call to the database for
each SQL statement, thereby increasing network
traffic and reducing performance (especially in a
client/server model).
With PL/SQL, you can combine
bine all these SQL
statements into a single program unit. The
© [email protected]
com DBMS Oracle / Page 75 of 125
RDBM
RDBMS using Oracle
application can send the entire block to the database instead of sending the SQL statements one at a time.
This significantly reduces the number of database calls. As the example illustrates, if the application is SQL
intensive, you can use PL/SQL blocks to group SQL statements before sending them to the Oracle database
server for execution.
Modularized program development: A basic unit in all PL/SQL programs is the block. Blocks can be in a
sequence or they can be nested in other blocks. Modularized program development has the following
advantages:

• You can group logically related statements within blocks.


• You can nest blocks inside larger blocks to build powerful programs.
• You can break your application into smaller modules. If you are designing a complex application,
PL/SQL allows you to break down the application into smaller, manageable, and logically related
modules.
• You can easily maintain and debug the code.
In PL/SQL, modularization is implemented using procedures, functions, and packages.
Integration with tools: The PL/SQL engine is integrated in Oracle tools such as Oracle Forms, Oracle Reports,
and so on. When you use these tools, the locally available PL/SQL engine processes the procedural
statements; only the SQL statements are passed to the database.
Portability: PL/SQL programs can run anywhere an Oracle server runs, irrespective of the operating system
and the platform. You do not need to customize them to each new environment. You can write portable
program packages and create libraries that can be reused in different environments.
Exception handling: PL/SQL enables you to handle exceptions efficiently. You can define separate blocks for
dealing with exceptions. PL/SQL shares the same data type system as SQL (with some extensions) and uses
the same expression syntax.
PL/SQL Block Structure
A PL/SQL block consists of three sections:
Declarative (optional): The declarative section begins with the keyword DECLARE and ends when the
executable section starts.
Executable (required): The executable section begins with the keyword BEGIN and ends with END. This
section essentially needs to have at least one statement. Observe that END is terminated with a semicolon.
The executable section of a PL/SQL block can, in turn, include any number of PL/SQL blocks.
Exception handling (optional): The exception section is nested within the executable section. This section
begins with the keyword EXCEPTION.
The End; section shows physical end of the PL/SQL block. In a PL/SQL block, the keywords DECLARE, BEGIN,
and EXCEPTION are not terminated by a semicolon. However, the keyword END, all SQL statements, and
PL/SQL statements must be terminated with a semicolon.
Block Types
A PL/SQL program comprises one or more blocks. These blocks can be entirely separate or nested within
another block. There are three types of blocks that make up a PL/SQL program. They are:
• Anonymous blocks
• Procedures
• Functions
Anonymous blocks: Anonymous blocks are unnamed blocks. They are declared inline at the point in an
application where they are to be executed and are compiled each time the application is executed. These
© [email protected] RDBMS Oracle / Page 76 of 125
RDBMS using Oracle
blocks are not stored in the database. They are passed to the PL/SQL engine for execution at run time.
Triggers in Oracle Developer components consist of such blocks. These anonymous blocks get executed at
run time because they are inline. If you want to execute the same block again, you have to rewrite the block.
You are unable to invoke or call the block that you wrote earlier because blocks are anonymous and do not
exist after they are executed.
Subprograms: Subprograms are complementary to anonymous blocks. They are named PL/SQL blocks that
are stored in the database. Because they are named and stored, you can invoke them whenever you want
(depending on your application). You can declare them either as procedures or as functions. You typically
use a procedure to perform an action and a function to compute and return a value.
You can store subprograms at the server or application level. Using Oracle Developer components (Forms,
Reports), you can declare procedures and functions as part of the application (a form or report) and call
them from other procedures, functions, and triggers within the same application whenever necessary.
SQL*Plus File Commands
SQL statements communicate with the Oracle server. SQL*Plus commands control the environment, format
query results, and manage files. You can use following commands:
SAVE
Use the SAVE command to store the current contents of the buffer in a file. In this way, you can store
frequently used scripts for use in the future.
SAVE filename
START
Use the START command to run a script in SQL*Plus.
START filename
You can also, alternatively, use the symbol @ to run a script.
@my_query
GET
Use the GET command to retrieve the saved script into SQL buffer.
GET filename
EDIT
Use the EDIT command to edit an existing script. This opens an editor with the script file in it. When you
have made the changes, quit the editor to return to the SQL*Plus command line. The "/" is a delimiter that
signifies the end of the statement. When encountered in a file, SQL*Plus runs the statement prior to this
delimiter. The delimiter must be the first character of a new line immediately following the statement.
EDIT filename
SPOOL
The SPOOL command stores query results in a file, or optionally sends the file to a printer. The SPOOL
command has been enhanced. You can now append to, or replace an existing file, where previously you
could only use SPOOL to create (and replace) a file. REPLACE is the default.
To spool output generated by commands in a script without displaying the output on the screen, use SET
TERMOUT OFF. SET TERMOUT OFF does not affect output from commands that run interactively.
You must use quotes around file names containing white space. To create a valid HTML file using SPOOL
APPEND commands, you must use PROMPT or a similar command to create the HTML page header and
© [email protected] RDBMS Oracle / Page 77 of 125
RDBMS using Oracle
footer. The SPOOL APPEND command does not parse HTML tags. SET SQLPLUSCOMPAT[IBILITY] to 9.2 or
earlier to disable the CREATE, APPEND and SAVE parameters.
SPOOL filename
Test the Output of a PL/SQL Block
PL/SQL does not have built-in input or output functionality. Therefore, you need to use predefined Oracle
packages for input and output. To generate output, you must enable output by executing the SET
SERVEROUTPUT ON command.
Use the PUT_LINE procedure of the DBMS_OUTPUT package to display the output. Pass the value that has to
be printed as argument to this procedure (as shown in the example). The procedure then outputs the
argument.
Example:
DBMS_OUTPUT.PUT_LINE('Hello World');
DBMS_OUTPUT.PUT_LINE(' The First Name of the Employee is ' || f_name);
Here f_name is a declared variable.
Let's have first PL/SQL block.
 Launch SQL*Plus
 Login to your user
 Give SET SERVEROUTPUT ON command
 Write code
BEGIN
DBMS_OUTPUT.PUT_LINE('Hello World');
END;
/
 Output occurred on SQL screen buffer only.

If you need you can store current PL/SQL block into a script file for future uses by issuing Save command.
Next time you can invoke it using Get command or Run it using @filename.
© [email protected] RDBMS Oracle / Page 78 of 125
RDBMS using Oracle
Lexical Units in a PL/SQL Block
Lexical units include letters, numerals, special characters, tabs, spaces, returns, and symbols.
Identifiers: Identifiers are the names given to PL/SQL objects. You have learned to identify valid and invalid
identifiers. Recall that keywords cannot be used as identifiers.
Quoted identifiers:
• Make identifiers case sensitive
• Include characters such as spaces
• Use reserved words
Examples:
"begin date" DATE;
"end date" DATE;
"exception thrown" BOOLEAN DEFAULT TRUE;
All subsequent usage of these variables should have double quotation marks. However, use of quoted
identifiers is not recommended.
Delimiters: Delimiters are symbols that have special meaning. You have already learned that the semicolon
(;) is used to terminate a SQL or PL/SQL statement. Therefore, ; is an example of a delimiter.
Literals: Any value that is assigned to a variable is a literal. Any character, numeral, Boolean, or date value
that is not an identifier is a literal. Literals are classified as:
• Character literals: All string literals have the data type CHAR or VARCHAR2 and are, therefore, called
character literals (for example, John, and 12C).
• Numeric literals: A numeric literal represents an integer or real value (for example, 428 and 1.276).
• Boolean literals: Values that are assigned to Boolean variables are Boolean literals. TRUE, FALSE, and
NULL are Boolean literals or keywords.
Comments: It is good programming practice to explain what a piece of code is trying to achieve. When you
include the explanation in a PL/SQL block, the compiler cannot interpret these instructions. There should be
a way in which you can indicate that these instructions need not be compiled. Comments are mainly used for
this purpose. Any instruction that is commented is not interpreted by the compiler. There are two types of
comments are often used in PL/SQL.

• Two hyphens (--) are used to comment a single line.


• The beginning and ending comment delimiters (/* and */) are used to comment multiple lines.
Variables
With PL/SQL, you can declare variables and then use them in SQL and procedural statements. Variables are
mainly used for storage of data and manipulation of stored values. Consider the PL/SQL statement retrieves
the first_name and department_id from the table. If you have to manipulate the first_name or the
department_id, then you have to store the retrieved value. Variables are used to temporarily store the
value. You can use the value stored in these variables for processing and manipulating the data. Variables
can store any PL/SQL object, such as variables, types, cursors, and subprograms.
Reusability is another advantage of declaring variables. After the variables are declared, you can use them
repeatedly in an application by referring to them multiple times in various statements.
Rules for defining a variable name:
• Must start with a letter
• Can include letters or numbers
© [email protected] RDBMS Oracle / Page 79 of 125
RDBMS using Oracle
• Can include special characters (such as $, _, and # )
• Must contain no more than 30 characters
• Must not include reserved words
Handling Variables in PL/SQL
You can use variables in the following ways

• Declare and initialize them in the declaration section: You can declare variables in the declarative
part of any PL/SQL block, subprogram, or package. Declarations allocate storage space for a value,
specify its data type, and name the storage location so that you can reference it. Declarations can
also assign an initial value and impose the NOT NULL constraint on the variable. Forward references
are not allowed. You must declare a variable before referencing it in other statements, including
other declarative statements.
• Use them and assign new values to them in the executable section: In the executable section, the
existing value of the variable can be replaced with the new value.
• Pass them as parameters to PL/SQL subprograms: Subprograms can take parameters. You can pass
variables as parameters to subprograms.
• Use them to hold the output of a PL/SQL subprogram: Variables can be used to hold the value that is
returned by a function.
Syntax:
identifier [CONSTANT] datatype [NOT NULL] [:= | DEFAULT expr];
Examples:
DECLARE
v_hiredate DATE;
v_deptno NUMBER(2) NOT NULL := 10;
v_location VARCHAR2(13) := 'Atlanta';
c_comm CONSTANT NUMBER := 1400;
Some Simple PL/SQL Blocks
declare declare
pa number(10,2); rate number(10,2); qty number(4);
dr number(3); amt number(10,2); dis number(10,2);
disamt number(10,2); netamt number(10,2);
ri number(6,2);
begin
si number(12,2);
rate:=1200; qty:=4; dis:=10;
begin amt:=rate * qty; disamt:= amt * dis/100;
pa := 5000; netamt:= amt - disamt;
dr :=2; dbms_output.put_line('Rate : '|| rate||'
Quantity : '||qty);
ri :=2.5;
dbms_output.put_line('Discount Rate : ' ||dis||'
si := pa * dr * ri / 100 ; Discount Amount : '||disamt);
dbms_output.put_line('Simple Interest : ' || si); dbms_output.put_line('Amount : '||amt||' Net
end; Amount : '||netamt);

/ end;
/

© [email protected] RDBMS Oracle / Page 80 of 125


RDBMS using Oracle
There is no Entry system is allowed on SQL*Plus we can use (&) substitution method as shown below but
remember all entries will be done before firing a PL/SQL block.

Nested PL/SQL blocks


Being procedural gives PL/SQL the ability to nest statements. You can nest blocks wherever an executable
statement is allowed, thus making the nested block a statement. If your executable section has code for
many logically related functionalities to support multiple business requirements, you can divide the
executable section into smaller blocks. An executable section (BEGIN … END) can contain nested blocks. An
exception section can contain nested blocks.
Example:
DECLARE
v_outer_variable VARCHAR2(20):='GLOBAL VARIABLE';
BEGIN
DECLARE
v_inner_variable VARCHAR2(20):='LOCAL VARIABLE';
BEGIN
DBMS_OUTPUT.PUT_LINE(v_inner_variable);
DBMS_OUTPUT.PUT_LINE(v_outer_variable);
END;
DBMS_OUTPUT.PUT_LINE(v_outer_variable);
END;

© [email protected] RDBMS Oracle / Page 81 of 125


RDBMS using Oracle
Operators in PL/SQL
The operations in an expression are performed in a particular order depending on their precedence
(priority). The following table shows the default order of operations from high priority to low priority:

Operator Operation
** Exponentiation
+, - Identity, negation
*, / Multiplication, division
+, -, || Addition, subtraction, concatenation
=, <, >, <=, >=, <>, !=, ~=, ^=,
Comparison
IS NULL, LIKE, BETWEEN, IN
NOT Logical negation
AND Conjunction
OR Inclusion
When working with nulls, you can avoid some common mistakes by keeping in mind the following rules:

• Comparisons involving nulls always yield NULL.


• Applying the logical operator NOT to a null yields NULL.
• In conditional control statements, if the condition yields NULL, its associated sequence
of statements is not executed.
SQL Statements in PL/SQL
In a PL/SQL block, you use SQL statements to retrieve and modify data from the database table. PL/SQL
supports data manipulation language (DML) and transaction control commands. You can use DML
commands to modify the data in a database table. However, remember the following points while using
DML statements and transaction control commands in PL/SQL blocks:
• The END keyword signals the end of a PL/SQL block, not the end of a transaction. Just as a block can
span multiple transactions, a transaction can span multiple blocks.
• PL/SQL does not directly support data definition language (DDL) statements, such as CREATE TABLE,
ALTER TABLE, or DROP TABLE. PL/SQL supports early binding, which cannot happen if applications
have to create database objects at run time by passing values.
• DDL statements cannot be directly executed. These statements are dynamic SQL statements.
Dynamic SQL statements are built as character strings at run time and can contain placeholders for
parameters. Therefore, you can use dynamic SQL to execute your DDL statements in PL/SQL.
• PL/SQL does not directly support data control language (DCL) statements, such as GRANT or REVOKE.
You can use dynamic SQL to execute them.
SELECT Statements in PL/SQL
Use the SELECT statement to retrieve data from the database.
Syntax:
SELECT select_list
INTO {variable_name[, variable_name] ... | record_name}
FROM table
[WHERE condition];

© [email protected] RDBMS Oracle / Page 82 of 125


RDBMS using Oracle
Follow the guidelines below while using the Select statement in PL/SQL block.
• Terminate each SQL statement with a semicolon (;).
• Every value retrieved must be stored in a variable by using the INTO clause.
• The WHERE clause is optional and can be used to specify input variables, constants, literals, and
PL/SQL expressions. However, when you use the INTO clause, you should fetch only one row; using
the WHERE clause is required in such cases.
• Specify the same number of variables in the INTO clause as the number of database columns in the
SELECT clause. Be sure that they correspond positionally and that their data types are compatible.
• Use group functions, such as SUM, in a SQL statement, because group functions apply to groups of
rows in a table.
INTO Clause
The INTO clause is mandatory and occurs between the SELECT and FROM clauses. It is used to specify the
names of variables that hold the values that SQL returns from the SELECT clause. You must specify one
variable for each item selected, and the order of the variables must correspond with the items selected. Use
the INTO clause to populate either PL/SQL variables or host variables.
Queries Must Return Only One Row
SELECT statements within a PL/SQL block fall into the ANSI classification of embedded SQL, for which the
following rule applies: queries must return only one row. A query that returns more than one row or no row
generates an error.
PL/SQL manages these errors by raising standard exceptions, which you can handle in the exception section
of the block with the NO_DATA_FOUND and TOO_MANY_ROWS exceptions. Include a WHERE condition in
the SQL statement so that the statement returns a single row.
How to Retrieve Multiple Rows from a Table and Operate on the Data
A SELECT statement with the INTO clause can retrieve only one row at a time. If your requirement is to
retrieve multiple rows and operate on the data, you can make use of explicit cursors.
Example:
DECLARE DECLARE
v_fname VARCHAR2(25); v_emp_hiredate date;
BEGIN v_emp_salary number(12,2);
SELECT first_name INTO v_fname BEGIN
FROM employees WHERE employee_id=200; SELECT hire_date, salary
DBMS_OUTPUT.PUT_LINE( INTO v_emp_hiredate, v_emp_salary
' First Name is : '||v_fname); FROM employees
END; WHERE employee_id = 100;
/ END;
/
DECLARE INTO v_sum_sal FROM employees
v_sum_sal NUMBER(10,2); WHERE department_id = v_deptno;
v_deptno NUMBER NOT NULL := 60; DBMS_OUTPUT.PUT_LINE ('The sum of salary is ' ||
BEGIN v_sum_sal);
SELECT SUM(salary) -- group function END;

© [email protected] RDBMS Oracle / Page 83 of 125


RDBMS using Oracle
%TYPE Attribute
PL/SQL variables are usually declared to hold and manipulate data stored in a database. When you declare
PL/SQL variables to hold column values, you must ensure that the variable is of the correct data type and
precision. If it is not, a PL/SQL error occurs during execution. If you have to design large subprograms, this
can be time consuming and error prone.
Rather than hard-coding the data type and precision of a variable, you can use the %TYPE
attribute to declare a variable according to another previously declared variable or database
column. The %TYPE attribute is most often used when the value stored in the variable is derived from a table
in the database. When you use the %TYPE attribute to declare a variable, you should prefix it with the
database table and column name. If you refer to a previously declared variable, prefix the variable name of
the previously declared variable to the variable being declared.
Advantages of the %TYPE Attribute
• You can avoid errors caused by data type mismatch or wrong precision.
• You can avoid hard-coding the data type of a variable.
• You need not change the variable declaration if the column definition changes. If you have already
declared some variables for a particular table without using the %TYPE attribute, the PL/SQL block
may throw errors if the column for which the variable is declared is altered. When you use the
%TYPE attribute, PL/SQL determines the data type and size of the variable when the block is
compiled. This ensures that such a variable is always compatible with the column that is used to
populate it.
Syntax :
Identifier table.column_name%TYPE;
Examples:
emp_lname employees.last_name%TYPE;
balance NUMBER(7,2);
min_balance balance%TYPE := 1000;
Only the TRUE, FALSE, and NULL values can be assigned to a Boolean variable. Conditional expressions use
the logical operators AND and OR and the unary operator NOT to check the variable values. The variables
always yield TRUE, FALSE, or NULL. Arithmetic, character, and date expressions can be used to return a
Boolean value.
Using PL/SQL to Manipulate Data
You manipulate data in the database by using the DML commands. You can issue the DML commands
INSERT, UPDATE, DELETE and MERGE without restriction in PL/SQL. Row locks (and table locks) are released
by including COMMIT or ROLLBACK statements in the PL/SQL code.
• The INSERT statement adds new rows to the table.
• The UPDATE statement modifies existing rows in the table.
• The DELETE statement removes rows from the table.
• The MERGE statement selects rows from one table to update or insert into another table. The
decision whether to update or insert into the target table is based on a condition in the ON clause.
Note: MERGE is a deterministic statement. That is, you cannot update the same row of the target table
multiple times in the same MERGE statement. You must have INSERT and UPDATE object privileges in the
target table and the SELECT privilege on the source table.

© [email protected] RDBMS Oracle / Page 84 of 125


RDBMS using Oracle
Add new employee information to the EMPLOYEES Increase the salary of all employees who are stock
table. clerks.
BEGIN DECLARE
INSERT INTO employees sal_increase employees.salary%TYPE := 800;
(employee_id, first_name, last_name, email, BEGIN
hire_date, job_id, salary) UPDATE employees
VALUES(employees_seq.NEXTVAL, 'Ruth', 'Cores', SET salary = salary + sal_increase
'RCORES',CURRENT_DATE, 'AD_ASST', 4000); WHERE job_id = 'ST_CLERK';
END; END;
/ /
Delete rows that belong to department 10 from the Insert or update rows in the copy_emp table to
employees table. match the employees table.
DECLARE BEGIN
deptno employees.department_id%TYPE := 10; MERGE INTO copy_emp c
BEGIN USING employees e
DELETE FROM employees ON (e.employee_id = c.empno)
WHERE department_id = deptno; WHEN MATCHED THEN
END; UPDATE SET
/ c.first_name = e.first_name,
c.last_name = e.last_name,
c.email = e.email,
c.phone_number = e.phone_number,
c.hire_date = e.hire_date,
c.job_id = e.job_id,
c.salary = e.salary,
c.commission_pct = e.commission_pct,
c.manager_id = e.manager_id,
c.department_id = e.department_id
WHEN NOT MATCHED THEN
INSERT VALUES(e.employee_id, e.first_name,
e.last_name,
e.email, e.phone_number, e.hire_date,
e.job_id,
e.salary, e.commission_pct, e.manager_id,
e.department_id);
END;
/

The MERGE statement inserts or updates rows in one table by using data from another table. Each row is
inserted or updated in the target table depending on an equijoin condition. The example shown matches
the employee_id in the copy_emp table to the employee_id in the employees table. If a match is found, the
row is updated to match the row in the employees table. If the row is not found, it is inserted into the
copy_emp table.

© [email protected] RDBMS Oracle / Page 85 of 125


RDBMS using Oracle
Composite Data Types
You have learned that variables of scalar data type can hold only one value, whereas a variable of composite
data type can hold multiple values of scalar data type or composite data type. There are two types of
composite data types:
• PL/SQL records: Records are used to treat related but dissimilar data as a logical unit. A PL/SQL
record can have variables of different types. For example, you can define a record to hold employee
details. This involves storing an employee number as NUMBER, a first name and a last name as
VARCHAR2, and so on. By creating a record to store employee details, you create a logical collective
unit. This makes data access and manipulation easier.
• PL/SQL collections: Collections are used to treat data as a single unit. Collections are of three types:
o INDEX BY tables or associative arrays
o Nested table
o VARRAY
Why Use Composite Data Types?
You have all the related data as a single unit. You can easily access and modify the data. Data is easier to
manage, relate, and transport if it is composite. An analogy is having a single bag for all your laptop
components rather than a separate bag for each component.
If both PL/SQL records and PL/SQL collections are composite types, how do you choose which one to use?
Use PL/SQL records when you want to store values of different data types that are logically related. If you
create a record to hold employee details, indicate that all the values stored are related because they provide
information about a particular employee.
Use PL/SQL collections when you want to store values of the same data type. Note that this data type can
also be of the composite type (such as records). You can define a collection to hold the first names of all
employees. You may have stored n names in the collection; however, name 1 is not related to name 2. The
relation between these names is only that they are employee names. These collections are similar to arrays
in programming languages such as C, C++, and Java.
PL/SQL Records
A record is a group of related data items stored in fields, each with its own name and data type. Each record
defined can have as many fields as necessary. Records can be assigned initial values and can be defined as
NOT NULL. Fields without initial values are initialized to NULL. The DEFAULT keyword can also be used when
defining fields. You can define RECORD types and declare user-defined records in the declarative part of any
block, subprogram, or package. You can declare and reference nested records. One record can be the
component of another record.
PL/SQL records are user-defined composite types. To use them:
1. Define the record in the declarative section of a PL/SQL block. The syntax for defining the record is
shown in the example.
2. Declare (and optionally initialize) the internal components of this record type.
Syntax:
TYPE type_name IS RECORD (field_declaration[, field_declaration]…);
identifier type_name;
Field Declaration :
field_name {field_type | variable%TYPE | table.column%TYPE | table%ROWTYPE}
[[NOT NULL] {:= | DEFAULT} expr]
© [email protected] RDBMS Oracle / Page 86 of 125
RDBMS using Oracle
Fields in a record are accessed with the name of the record. To reference or initialize an individual field, use
dot notation:
record_name.field_name
For example, you reference the job_id field in the emp_record record as follows:
emp_record.job_id
You can then assign a value to the record field:
emp_record.job_id := 'ST_CLERK';
In a block or subprogram, user-defined records are instantiated when you enter the block or subprogram.
They cease to exist when you exit the block or subprogram.
Example:
DECLARE
type t_rec is record
(v_sal number(8),
v_minsal number(8) default 1000,
v_hire_date employees.hire_date%type,
v_rec1 employees%rowtype);
v_myrec t_rec;
BEGIN
v_myrec.v_sal := v_myrec.v_minsal + 500;
v_myrec.v_hire_date := sysdate;
SELECT * INTO v_myrec.v_rec1
FROM employees WHERE employee_id = 100;
DBMS_OUTPUT.PUT_LINE(v_myrec.v_rec1.last_name ||' '||
to_char(v_myrec.v_hire_date) ||' '|| to_char(v_myrec.v_sal));
END;
%ROWTYPE Attribute
You have learned that %TYPE is used to declare a variable of a column type. The variable has the same data
type and size as the table column. The benefit of %TYPE is that you do not have to change the variable if the
column is altered. Also, if the variable is used in any calculations, you need not worry about its precision.
The %ROWTYPE attribute is used to declare a record that can hold an entire row of a table or view. The fields
in the record take their names and data types from the columns of the table or view. The record can also
store an entire row of data fetched from a cursor or cursor variable.
Syntax for declaring a record
DECLARE
identifier reference%ROWTYPE;
Example
DECLARE
emp_record employees%ROWTYPE;

© [email protected] RDBMS Oracle / Page 87 of 125


RDBMS using Oracle
Advantages
The advantages of using the %ROWTYPE attribute are listed in the below. Use the %ROWTYPE attribute
when you are not sure about the structure of the underlying database table.
The main advantage of using %ROWTYPE is that it simplifies maintenance. Using %ROWTYPE ensures that
the data types of the variables declared with this attribute change dynamically when the underlying table is
altered. If a DDL statement changes the columns in a table, then the PL/SQL program unit is invalidated.
When the program is recompiled, it will automatically reflect the new table format.
The %ROWTYPE attribute is particularly useful when you want to retrieve an entire row from a table. In the
absence of this attribute, you would be forced to declare a variable for each of the columns retrieved by the
SELECT statement.
DECLARE
v_employee_number number:= 124;
v_emp_rec employees%ROWTYPE;
BEGIN
SELECT * INTO v_emp_rec FROM employees
WHERE employee_id = v_employee_number;
INSERT INTO retired_emps(empno, ename, job, mgr,
hiredate, leavedate, sal, comm, deptno)
VALUES (v_emp_rec.employee_id, v_emp_rec.last_name,
v_emp_rec.job_id, v_emp_rec.manager_id,
v_emp_rec.hire_date, SYSDATE,
v_emp_rec.salary, v_emp_rec.commission_pct,
v_emp_rec.department_id);
END;
/
Inserting row using record type
DECLARE
v_employee_number number:= 124;
v_emp_rec retired_emps%ROWTYPE;
BEGIN
SELECT employee_id, last_name, job_id, manager_id, hire_date, hire_date, salary, commission_pct,
department_id INTO v_emp_rec FROM employees WHERE employee_id = v_employee_number;
INSERT INTO retired_emps VALUES v_emp_rec;
END;
/
SELECT * FROM retired_emps;
Update using record type
DECLARE
v_employee_number number:= 124;
v_emp_rec retired_emps%ROWTYPE;
BEGIN
SELECT * INTO v_emp_rec FROM retired_emps;
v_emp_rec.leavedate:=CURRENT_DATE;
UPDATE retired_emps SET ROW = v_emp_rec WHERE empno=v_employee_number;
END;
/
SELECT * FROM retired_emps;

© [email protected] RDBMS Oracle / Page 88 of 125


RDBMS using Oracle
Controlling Flow of Execution
You can change the logical flow of statements within the PL/SQL block with a number of control structures.
There are four types of PL/SQL control structures:
• Conditional constructs with the IF statement
• CASE expressions
• LOOP control structures
• CONTINUE statement
IF Statement
The structure of the PL/SQL IF statement is similar to the structure of IF statements in other procedural
languages. It allows PL/SQL to perform actions selectively based on conditions.
Syntax:
IF condition THEN
statements;
[ELSIF condition THEN
statements;]
[ELSE
statements;]
END IF;
ELSIF and ELSE are optional in an IF statement. You can have any number of ELSIF keywords but only one
ELSE keyword in your IF statement. END IF marks the end of an IF statement and must be terminated by a
semicolon.
Example :
DECLARE DECLARE
v_myage number:=31; v_myage number:=31;
BEGIN BEGIN
IF v_myage < 11 THEN IF v_myage < 11 THEN
DBMS_OUTPUT.PUT_LINE(' I am a child '); DBMS_OUTPUT.PUT_LINE(' I am a child ');
END IF; ELSE
END; DBMS_OUTPUT.PUT_LINE('I am not a child ');
/ END IF;
END;
/
DECLARE ELSIF v_myage < 40 THEN
v_myage number:=31; DBMS_OUTPUT.PUT_LINE(' I am in my
BEGIN thirties');
IF v_myage < 11 THEN ELSE
DBMS_OUTPUT.PUT_LINE(' I am a child '); DBMS_OUTPUT.PUT_LINE(' I am
ELSIF v_myage < 20 THEN always young ');
DBMS_OUTPUT.PUT_LINE(' I am young '); END IF;
ELSIF v_myage < 30 THEN END;
DBMS_OUTPUT.PUT_LINE(' I am in my /
twenties');
© [email protected] RDBMS Oracle / Page 89 of 125
RDBMS using Oracle
NULL Value in IF Statement
In the example shown below, the variable v_myage is declared but not initialized. The condition in the IF
statement returns NULL rather than TRUE or FALSE. In such a case, the control goes to the ELSE statement.
DECLARE
v_myage number;
BEGIN
IF v_myage < 11 THEN
DBMS_OUTPUT.PUT_LINE(' I am a child ');
ELSE
DBMS_OUTPUT.PUT_LINE(' I am not a child ');
END IF;
END;
/
Guidelines About IF..THEN…Else…End IF;
• You can perform actions selectively based on conditions that are being met.
• When writing code, remember the spelling of the keywords:
o ELSIF is one word.
o END IF is two words.
• If the controlling Boolean condition is TRUE, the associated sequence of statements is executed; if
the controlling Boolean condition is FALSE or NULL, the associated sequence of statements is passed
over. Any number of ELSIF clauses are permitted.
• Indent the conditionally executed statements for clarity.
CASE Expressions
A CASE expression returns a result based on one or more alternatives. To return the result, the CASE
expression uses a selector, which is an expression whose value is used to return one of several alternatives.
The selector is followed by one or more WHEN clauses that are checked sequentially. The value of the
selector determines which result is returned. If the value of the selector equals the value of a WHEN clause
expression, that WHEN clause is executed and that result is returned.
PL/SQL also provides a searched CASE expression, which has the form:
CASE
WHEN search_condition1 THEN result1
WHEN search_condition2 THEN result2
...
WHEN search_conditionN THEN result
[ELSE resultN+1]
END;
A searched CASE expression has no selector. Furthermore, its WHEN clauses contain search conditions that
yield a Boolean value rather than expressions that can yield a value of any type.

© [email protected] RDBMS Oracle / Page 90 of 125


RDBMS using Oracle
DECLARE DECLARE
v_grade CHAR(1) := UPPER('&grade'); v_grade CHAR(1) := UPPER('&grade');
appraisal VARCHAR2(20); appraisal VARCHAR2(20);
BEGIN BEGIN
appraisal := CASE v_grade appraisal := CASE
WHEN 'A' THEN 'Excellent' WHEN v_grade = 'A' THEN 'Excellent'
WHEN 'B' THEN 'Very Good' WHEN v_grade IN ('B','C') THEN 'Good'
WHEN 'C' THEN 'Good' ELSE 'No such grade'
ELSE 'No such grade' END;
END; DBMS_OUTPUT.PUT_LINE ('Grade: '|| v_grade || '
DBMS_OUTPUT.PUT_LINE ('Grade: '|| v_grade || ' Appraisal ' || appraisal);
Appraisal ' || appraisal); END;
END; /
/

CASE Statement
Recall the use of the IF statement. You may include n number of PL/SQL statements in the THEN clause and
also in the ELSE clause. Similarly, you can include statements in the CASE statement. The CASE statement is
more readable compared to multiple IF and ELSIF statements.
How a CASE Expression Differs from a CASE Statement
A CASE expression evaluates the condition and returns a value, whereas a CASE statement evaluates the
condition and performs an action. A CASE statement can be a complete PL/SQL block.
• CASE statements end with END CASE;
• CASE expressions end with END;
Example :
DECLARE
v_deptid NUMBER;
v_deptname VARCHAR2(20);
v_emps NUMBER;
v_mngid NUMBER:= 108;
BEGIN
CASE v_mngid
WHEN 108 THEN
SELECT department_id, department_name INTO v_deptid, v_deptname
FROM departments WHERE manager_id=108;
SELECT count(*) INTO v_emps FROM employees WHERE department_id=v_deptid;
WHEN 200 THEN
...
END CASE;
DBMS_OUTPUT.PUT_LINE ('You are working in the '|| deptname||' department.
There are '||v_emps ||' employees in this department');
END;
/
Iterative Control: LOOP Statements
PL/SQL provides several facilities to structure loops to repeat a statement or sequence of statements
multiple times. Loops are mainly used to execute statements repeatedly until an exit condition is reached. It
is mandatory to have an exit condition in a loop; otherwise, the loop is infinite.
Looping constructs are the second type of control structure. PL/SQL provides the following types of loops:
© [email protected] RDBMS Oracle / Page 91 of 125
RDBMS using Oracle
• Basic loop that performs repetitive actions without overall conditions
• FOR loops that perform iterative actions based on a count
• WHILE loops that perform iterative actions based on a condition
An EXIT statement can be used to terminate loops. A basic loop must have an EXIT.
SRNO Syntax Example
1. LOOP BEGIN
statement1; Loop
... DBMS_OUTPUT.PUT_LINE('India');
END LOOP; End Loop;
End;
NOTE : The above loop statement will be an infinite loop because there is no limitation is given for execution
of iterations. There must be a condition to control the execution of a loop control statements as shown
below.
2. LOOP DECLARE
statement1; cnt number(3):=1;
... BEGIN
EXIT ; LOOP
END LOOP; DBMS_OUTPUT.PUT_LINE('India');
cnt := cnt + 1;
IF cnt >10 THEN
EXIT;
END IF;
END LOOP;
END;
/
3. LOOP DECLARE
statement1; cnt number(3):=1;
... BEGIN
EXIT [WHEN condition]; LOOP
END LOOP; DBMS_OUTPUT.PUT_LINE('India');
cnt := cnt + 1;
EXIT WHEN cnt >10 ;
END LOOP;
END;
/
Another Example
DECLARE
v_countryid locations.country_id%TYPE := 'CA';
v_loc_id locations.location_id%TYPE;
v_counter NUMBER(2) := 1;
v_new_city locations.city%TYPE := 'Montreal';
BEGIN
SELECT MAX(location_id) INTO v_loc_id FROM locations WHERE country_id = v_countryid;
LOOP
INSERT INTO locations(location_id, city, country_id)
VALUES((v_loc_id + v_counter), v_new_city, v_countryid);
v_counter := v_counter + 1;
EXIT WHEN v_counter > 3;
END LOOP;
END;
/
4. WHILE condition LOOP DECLARE
statement1; i NUMBER(3):=1;
statement2; BEGIN
... WHILE i<=10 LOOP
© [email protected] RDBMS Oracle / Page 92 of 125
RDBMS using Oracle
END LOOP; dbms_output.put_line(i);
i:=i+1;
END LOOP;
END;
/
Another Example :
DECLARE
v_countryid locations.country_id%TYPE := 'CA';
v_loc_id locations.location_id%TYPE;
v_new_city locations.city%TYPE := 'Montreal';
v_counter NUMBER := 1;
BEGIN
SELECT MAX(location_id) INTO v_loc_id FROM locations WHERE country_id = v_countryid;
WHILE v_counter <= 3 LOOP
INSERT INTO locations(location_id, city, country_id)
VALUES((v_loc_id + v_counter), v_new_city, v_countryid);
v_counter := v_counter + 1;
END LOOP;
END;
/
5. FOR counter IN [REVERSE] BEGIN
lower_bound..upper_bound LOOP FOR i IN 1..10 LOOP
statement1; dbms_output.put_line(i);
statement2; END LOOP;
... END;
END LOOP; /
Notes:
• No Need to declare loop counter/index variable. It is declared implicitly as an integer.
• No need to specify the condition. Maintained implicitly using Lower and Upper bounds.
• No need to do increment.
• The .. is a range operator.
• Reference the counter within the loop only; it is undefined outside the loop.
• Do not reference the counter as the target of an assignment.
• Neither loop bound should be NULL.
DECLARE Reverse for loop
v_lower NUMBER := 1; BEGIN
v_upper NUMBER := 100; FOR i IN REVERSE 1..10 LOOP
BEGIN dbms_output.put (i);
FOR i IN v_lower..v_upper LOOP END LOOP;
dbms_output.put_line(i); dbms_output.put _line(' ');
END LOOP; END;
END; /
/ Output : 10 9 8 7 6 5 4 3 2 1

Nested Loops and Labels


You can nest FOR, WHILE, and basic loops within one another. The termination of a nested loop does not
terminate the enclosing loop unless an exception was raised. However, you can label loops and exit the
outer loop with the EXIT statement.
Label names follow the same rules as other identifiers. A label is placed before a statement, either on the
same line or on a separate line. White space is insignificant in all PL/SQL parsing except inside literals. Label
basic loops by placing the label before the word LOOP within label delimiters (<<label>>). In FOR and WHILE
loops, place the label before FOR or WHILE.
If the loop is labeled, the label name can be included (optionally) after the END LOOP statement for clarity.
© [email protected] RDBMS Oracle / Page 93 of 125
RDBMS using Oracle
...
BEGIN
<<Outer_loop>>
LOOP
v_counter := v_counter+1;
EXIT WHEN v_counter>10;
<<Inner_loop>>
LOOP
...
EXIT Outer_loop WHEN total_done = 'YES';
-- Leave both loops
EXIT WHEN inner_done = 'YES';
-- Leave inner loop only
...
END LOOP Inner_loop;
...
END LOOP Outer_loop;
END;
/
In the example above, there are two loops. The outer loop is identified by the label <<Outer_Loop>> and the
inner loop is identified by the label <<Inner_Loop>>. The identifiers are placed before the word LOOP within
label delimiters (<<label>>). The inner loop is nested within the outer loop. The label names are included
after the END LOOP statements for clarity.
Example:
begin begin begin
for i in 1..5 loop for i in 1..5 loop for i in 1..5 loop
for j in 1..5 loop for j in 1..i loop for j in 1..i loop
dbms_output.put(' * '); dbms_output.put(' * '); dbms_output.put(j);
end loop; end loop; end loop;
dbms_output.put_line(' '); dbms_output.put_line(' '); dbms_output.put_line(' ');
end loop; end loop; end loop;
end; end; end;
/ / /
begin declare declare
for i in 1..5 loop n number:=1; n number:=10;
for j in 1..i loop begin begin
dbms_output.put(i); for i in 1..4 loop for i in 1..4 loop
end loop; for j in 1..i loop for j in reverse 1..i loop
dbms_output.put_line(' '); dbms_output.put(n||' '); dbms_output.put(n||' ');
end loop; n:= n+ 1; n:= n - 1;
end; end loop; end loop;
/ dbms_output.put_line(' '); dbms_output.put_line(' ');
end loop; end loop;
end; end;
/ /
PL/SQL CONTINUE Statement
The CONTINUE statement enables you to transfer control within a loop back to a new iteration or to leave
the loop. Many other programming languages have this functionality. With the Oracle Database 11g release,
PL/SQL also offers this functionality. Before the Oracle Database 11g release, you could code a workaround
using Boolean variables and conditional statements to simulate the CONTINUE programmatic functionality.
In some cases, the workarounds are less efficient.
© [email protected] RDBMS Oracle / Page 94 of 125
RDBMS using Oracle
The CONTINUE statement offers you a simplified means to control loop iterations. It may be more efficient
than previous coding workarounds.
The CONTINUE statement is commonly used to filter data inside a loop body before the main processing
begins.
PL/SQL Block OUTPUT
DECLARE
Total is: 1
v_total SIMPLE_INTEGER := 0;
Out of Loop Total is: 2
BEGIN
Total is: 4
FOR i IN 1..10 LOOP
Out of Loop Total is: 6
v_total := v_total + i;
Total is: 9
dbms_output.put_line
Out of Loop Total is: 12
('Total is: '|| v_total);
Total is: 16
CONTINUE WHEN i > 5;
Out of Loop Total is: 20
v_total := v_total + i;
Total is: 25
dbms_output.put_line
Out of Loop Total is: 30
('Out of Loop Total is: '|| v_total);
Total is: 36
END LOOP;
Total is: 43
END;
Total is: 51
/
Total is: 60
Total is: 70

Handling Exceptions with PL/SQL


An exception is a PL/SQL error that is raised during program execution. An exception can be raised: Implicitly
by the Oracle server or explicitly by the program. An exception can be handled by trapping it with a handler
or by propagating it to the calling environment.
You have written PL/SQL blocks with a declarative section (beginning with the DECLARE keyword) and an
executable section (beginning and ending with the BEGIN and END keywords, respectively). For exception
handling, you include another optional section called the exception section. This section begins with the
EXCEPTION keyword. If present, this is the last section in a PL/SQL block. Examine the EXCEPTION section of
the code in the example below.
DECLARE
v_lname VARCHAR2(15);
BEGIN
SELECT last_name INTO v_lname FROM employees
WHERE first_name='John';
DBMS_OUTPUT.PUT_LINE ('John''s last name is :'||v_lname);
EXCEPTION
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT(' Your select statement retrieved multiple rows');
DBMS_OUTPUT.PUT_LINE('Consider using a cursor.');
END;
/
Unlike earlier, the PL/SQL program does not terminate abruptly. When the exception is raised, the control
shifts to the exception section and all the statements in the exception section are executed. The PL/SQL
block terminates with normal, successful completion.

© [email protected] RDBMS Oracle / Page 95 of 125


RDBMS using Oracle
Trapping an Exception
Include an EXCEPTION section in your PL/SQL program to trap exceptions. If the exception is raised in the
executable section of the block, processing then branches to the corresponding exception handler in the
exception section of the block. If PL/SQL successfully handles the exception, the exception does not
propagate to the enclosing block or to the calling environment. The PL/SQL block terminates successfully.
Propagating an Exception
If the exception is raised in the executable section of the block and there is no corresponding exception
handler, then the PL/SQL block terminates with failure and the exception is propagated to an enclosing block
or to the calling environment. The calling environment can be any application (such as SQL*Plus that invokes
the PL/SQL program).
Exception Types
There are three types of exceptions.

Exception Description Directions for Handling


Predefined One of approximately 20 You need not declare these exceptions.
Oracle Server errors that occur most They are predefined by the Oracle server
error often in PL/SQL code and are raised implicitly.
Non- Any other standard Oracle You need to declare these within the
predefined Server error declarative section; the Oracle server will
Oracle Server raise the error implicitly, and you can catch
error for the error in the exception handler.
User-defined A condition that the Declare in the declarative section and raise
error developer determines is explicitly.
abnormal
Note: Some application tools with client-side PL/SQL (such as Oracle Developer Forms) have their own
exceptions.
Trapping Exceptions
You can trap any error by including a corresponding handler within the exception-handling section of the
PL/SQL block. Each handler consists of a WHEN clause, which specifies an exception name, followed by a
sequence of statements to be executed when that exception is raised. You can include any number of
handlers within an EXCEPTION section to handle specific exceptions. However, you cannot have multiple
handlers for a single exception.
Syntax:
EXCEPTION
WHEN exception1 [OR exception2 . . .] THEN
statement1;
statement2;
...
[WHEN exception3 [OR exception4 . . .] THEN
statement1;
statement2;
. . .]
[WHEN OTHERS THEN
statement1;
statement2;
. . .]

© [email protected] RDBMS Oracle / Page 96 of 125


RDBMS using Oracle
Trapping Predefined Oracle Server Errors
Trap a predefined Oracle server error by referencing its predefined name within the corresponding
exception-handling routine. Sample predefined exceptions:
• NO_DATA_FOUND
• TOO_MANY_ROWS
• INVALID_CURSOR
• ZERO_DIVIDE
• DUP_VAL_ON_INDEX
PL/SQL declares predefined exceptions in the STANDARD package.

Exception Name Oracle Server Description


Error
Number
ACCESS_INTO_NULL ORA-06530 Attempted to assign values to the
attributes of an uninitialized object
CASE_NOT_FOUND ORA-06592 None of the choices in the WHEN clauses of
a CASE statement are selected, and there
is no ELSE clause.
COLLECTION_IS_NULL ORA-06531 Attempted to apply collection methods
other than EXISTS to an uninitialized
nested table or VARRAY
CURSOR_ALREADY_OPEN ORA-06511 Attempted to open an already open cursor

DUP_VAL_ON_INDEX ORA-00001 Attempted to insert a duplicate value

INVALID_CURSOR ORA-01001 Illegal cursor operation occurred.

INVALID_NUMBER ORA-01722 Conversion of character string to number


fails.
LOGIN_DENIED ORA-01017 Logging on to the Oracle server with an
invalid username or password
NO_DATA_FOUND ORA-01403 Single row SELECT returned no data.

NOT_LOGGED_ON ORA-01012 PL/SQL program issues a database call


without being connected to the Oracle
server.
PROGRAM_ERROR ORA-06501 PL/SQL has an internal problem.

ROWTYPE_MISMATCH ORA-06504 Host cursor variable and PL/SQL cursor


variable involved in an assignment have
incompatible return types.
STORAGE_ERROR ORA-06500 PL/SQL ran out of memory, or memory is
corrupted.

SUBSCRIPT_BEYOND_COUNT ORA-06533 Referenced a nested table or VARRAY element


by using an index number larger than the
number of elements in the collection

© [email protected] RDBMS Oracle / Page 97 of 125


RDBMS using Oracle
SUBSCRIPT_OUTSIDE_LIMIT ORA-06532 Referenced a nested table or VARRAY element
by using an index number that is outside the
legal range (for example, –1)
SYS_INVALID_ROWID ORA-01410 The conversion of a character string into a
universal ROWID fails because the character
string does not represent a valid ROWID.
TIMEOUT_ON_RESOURCE ORA-00051 Time-out occurred while the Oracle server was
waiting for a resource.

TOO_MANY_ROWS ORA-01422 Single-row SELECT returned more than one


row.
VALUE_ERROR ORA-06502 Arithmetic, conversion, truncation, or size-
constraint error occurred.

ZERO_DIVIDE ORA-01476 Attempted to divide by zero

Trapping Non-Predefined Oracle Server Errors


Non-predefined exceptions are similar to predefined exceptions; however, they are not defined as PL/SQL
exceptions in the Oracle server. They are standard Oracle errors. You create exceptions with standard Oracle
errors by using the PRAGMA EXCEPTION_INIT function. Such exceptions are called non-predefined
exceptions.
You can trap a non-predefined Oracle server error by declaring it first. The declared exception is raised
implicitly. In PL/SQL, PRAGMA EXCEPTION_INIT tells the compiler to associate an exception name with an
Oracle error number. That enables you to refer to any internal exception by name and to write a specific
handler for it.
Note: PRAGMA (also called pseudoinstructions) is the keyword that signifies that the statement is a compiler
directive, which is not processed when the PL/SQL block is executed. Rather, it directs the PL/SQL compiler
to interpret all occurrences of the exception name within the block as the associated Oracle server error
number.
Example:
DECLARE
e_insert_excep EXCEPTION;
PRAGMA EXCEPTION_INIT(e_insert_excep, -01400);
BEGIN
INSERT INTO departments (department_id, department_name) VALUES (280, NULL);
EXCEPTION
WHEN e_insert_excep THEN
DBMS_OUTPUT.PUT_LINE('INSERT OPERATION FAILED');
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/
The example above tries to insert the value NULL for the department_name column of the departments
table. However, the operation is not successful because department_name is a NOT NULL column. The
SQLERRM function is used to retrieve the error message.
© [email protected] RDBMS Oracle / Page 98 of 125
RDBMS using Oracle
When an exception occurs, you can identify the associated error code or error message by using two
functions. Based on the values of the code or the message, you can decide which subsequent actions to take.

• SQLCODE returns the Oracle error number for internal exceptions.


• SQLERRM returns the message associated with the error number.
Example:
DECLARE
error_code NUMBER;
error_message VARCHAR2(255);
BEGIN
...
EXCEPTION
...
WHEN OTHERS THEN
ROLLBACK;
error_code := SQLCODE ;
error_message := SQLERRM ;
INSERT INTO errors (e_user, e_date, error_code, error_message)
VALUES(USER,SYSDATE,error_code,error_message);
END;
/
Trapping User-Defined Exceptions
PL/SQL enables you to define your own exceptions depending on the requirements of your application. For
example, you may prompt the user to enter a department number. Define an exception to deal with error
conditions in the input data. Check whether the department number exists. If it does not, then you may have
to raise the user-defined exception.
PL/SQL exceptions must be:
• Declared in the declarative section of a PL/SQL block
• Raised explicitly with RAISE statements
• Handled in the EXCEPTION section
You trap a user-defined exception by declaring it and raising it explicitly.
1. Declare the name of the user-defined exception within the declarative section.
Syntax:
exception EXCEPTION;
In the syntax, exception is the name of the exception.
2. Use the RAISE statement to raise the exception explicitly within the executable section.
Syntax:
RAISE exception;
In the syntax, exception is the previously declared exception.
3. Reference the declared exception within the corresponding exception-handling routine.
© [email protected] RDBMS Oracle / Page 99 of 125
RDBMS using Oracle
Example:
Write block tat updates the department_name of a department. The user supplies the department number
and the new name. If the supplied department number does not exist, no rows are updated in the
departments table. Raise an exception and print a message for the user that an invalid department number
was entered.
Note: Use the RAISE statement by itself within an exception handler to raise the same exception again and
propagate it back to the calling environment.
DECLARE
v_deptno NUMBER := 500;
v_name VARCHAR2(20) := 'Testing';
e_invalid_department EXCEPTION;
BEGIN
UPDATE departments SET department_name = v_name WHERE department_id = v_deptno;
IF SQL % NOTFOUND THEN
RAISE e_invalid_department;
END IF;
COMMIT;
EXCEPTION
WHEN e_invalid_department THEN
DBMS_OUTPUT.PUT_LINE('No such department id.');
END;
/
RAISE_APPLICATION_ERROR Procedure
Use the RAISE_APPLICATION_ERROR procedure to communicate a predefined exception interactively by
returning a nonstandard error code and error message. With RAISE_APPLICATION_ERROR, you can report
errors to your application and avoid returning unhandled exceptions. You can use this procedure to issue
user-defined error messages from stored subprograms.
Syntax:
raise_application_error (error_number, message[, {TRUE | FALSE}]);
The RAISE_APPLICATION_ERROR procedure can be used in either the executable section or the exception
section of a PL/SQL program, or both. The returned error is consistent with how the Oracle server produces
a predefined, non-predefined, or user-defined error. The error number and message are displayed to the
user.
Used in Executable section Used in Exception section
BEGIN ...
... EXCEPTION
DELETE FROM employees WHERE manager_id = WHEN NO_DATA_FOUND THEN
v_mgr;
RAISE_APPLICATION_ERROR (-20201,
IF SQL%NOTFOUND THEN
'Manager is not a valid employee.');
RAISE_APPLICATION_ERROR(-20202,
END;
'This is not a valid manager'); /
END IF;
...

© [email protected] RDBMS Oracle / Page 100 of 125


RDBMS using Oracle
SQL Cursor
You have already learned that you can include SQL statements that return a single row in a PL/SQL block.
The data retrieved by the SQL statement should be held in variables using the INTO clause.
Where Does the Oracle Server Process SQL Statements?
The Oracle server allocates a private memory area called the context area for processing SQL statements.
The SQL statement is parsed and processed in this area. Information required for processing and information
retrieved after processing are all stored in this area. You have no control over this area because it is
internally managed by the Oracle server.
A cursor is a pointer to the context area. However, this cursor is an implicit cursor and is automatically
managed by the Oracle server. When the executable block issues a SQL statement, PL/SQL creates an
implicit cursor.
Types of Cursors
There are two types of cursors:

• Implicit: An implicit cursor is created and managed by the Oracle server. You do not have access to
it. The Oracle server creates such a cursor when it has to execute a SQL statement.
• Explicit: As a programmer, you may want to retrieve multiple rows from a database table, have a
pointer to each row that is retrieved, and work on the rows one at a time. In such cases, you can
declare cursors explicitly depending on your business requirements. A cursor that is declared by
programmers is called an explicit cursor. You declare such a cursor in the declarative section of a
PL/SQL block.
SQL Cursor Attributes for Implicit Cursors
SQL cursor attributes enable you to evaluate what happened when an implicit cursor was last used. Use
these attributes in PL/SQL statements but not in SQL statements. You can test following attributes
SQL%FOUND Boolean attribute that evaluates to TRUE if the most recent SQL statement returned at
least one row
SQL%NOTFOUND Boolean attribute that evaluates to TRUE if the most recent SQL statement did not
return even one row
SQL%ROWCOUNT An integer value that represents the number of rows affected by the most recent SQL
statement
These attributes can be checked in the executable section of a block to gather information after the
appropriate DML command executes. These cursor attributes are used with implicit cursors that are
automatically created by PL/SQL and for which you do not know the names. Therefore, you use SQL instead
of the cursor name.
Example:
DECLARE DECLARE
v_rows_deleted VARCHAR2(30) nr number(4);
v_empno employees.employee_id%TYPE := 176; BEGIN
BEGIN UPDATE emp2 SET sal=sal*1.15 WHERE sal>1500;
DELETE FROM employees nr := sql%rowcount;
WHERE employee_id = v_empno; IF sql%rowcount>0 THEN
v_rows_deleted := (SQL%ROWCOUNT || dbms_output.put_line(nr|| ' rows affected');
' row deleted.'); ELSE
DBMS_OUTPUT.PUT_LINE (v_rows_deleted); dbms_output.put_line('No Such Record');
END; END IF;
END;

© [email protected] RDBMS Oracle / Page 101 of 125


RDBMS using Oracle
Explicit Cursor Operations
You declare explicit cursors in PL/SQL when you have a SELECT statement that returns multiple rows. You
can process each row returned by the SELECT statement.

The set of rows returned by a multiple-row


multiple row query is called the active set. Its size is the number of rows that
meet your search criteria. The diagram shows how an explicit cursor "points" to the current row in the active
set. This enables your program to process the rows one at a time.
Explicit cursor functions:
• Can perform row-by-row
row processing beyond the first row returned by a query
• Keep track
ack of the row that is currently being processed
• Enable the programmer to manually control explicit cursors in the PL/SQL block

Controlling Explicit Cursors


Now that you have a conceptual understanding of cursors, review the steps to use them.
1. In the declarative section of a PL/SQL block, declare the cursor by naming it and defining the structure of
the query to be associated with it.
2. Open the cursor. The OPEN statement executes the query Open the cursor.
Cursor
and binds any variables that are referenced. Rows
Row identified pointer

by the query are called the active set and are now available
for fetching.
Fetch a row.
3. Fetch data from the cursor. after each fetch you test the Cursor
pointer
cursor for any existing row. If there are no more rows to
process, you must close the cursor.
Cursor
Close the cursor.
4. Close thee cursor. The CLOSE statement releases the active pointer

set of rows. It is now possible to reopen the cursor to


establish a fresh active set.
© [email protected]
com BMS Oracle / Page 102 of 125
RDBM
RDBMS using Oracle
Using Explicit Cursor
Declaring the Cursor
Use the CURSOR statement to declare an explicit cursor. You can reference variables within the query, but
you must declare them before the CURSOR statement.
Syntax:
CURSOR cursor_name IS select_statement;
• Do not include the INTO clause in the cursor declaration because it appears later in the FETCH
statement.
• If processing rows in a specific sequence is required, use the ORDER BY clause in the query.
• The cursor can be any valid SELECT statement, including joins, subqueries, and so on.
Opening the Cursor
The OPEN statement executes the query associated with the cursor, identifies the active set, and positions
the cursor pointer at the first row. The OPEN statement is included in the executable section of the PL/SQL
block.
Syntax:
OPEN cursor_name;
OPEN is an executable statement that performs the following operations:
1. Dynamically allocates memory for a context area
2. Parses the SELECT statement
3. Binds the input variables (sets the values for the input variables by obtaining their memory
addresses)
4. Identifies the active set (the set of rows that satisfy the search criteria). Rows in the active set are
not retrieved into variables when the OPEN statement is executed. Rather, the FETCH statement
retrieves the rows from the cursor to the variables.
5. Positions the pointer to the first row in the active set
Note: If a query returns no rows when the cursor is opened, PL/SQL does not raise an exception. You can find
out the number of rows returned with an explicit cursor by using the <cursor_name>%ROWCOUNT attribute.
Fetching Data from the Cursor
The FETCH statement retrieves the rows from the cursor one at a time. After each fetch, the cursor advances
to the next row in the active set. You can use the %NOTFOUND attribute to determine whether the entire
active set has been retrieved. To fetch all rows, you must use loops.
Syntax:
FETCH cursor_name INTO [variable1, variable2, ...] | record_name];
The FETCH statement performs the following operations:
1. Reads the data for the current row into the output PL/SQL variables
2. Advances the pointer to the next row in the active set
You can include the same number of variables in the INTO clause of the FETCH statement as there are
columns in the SELECT statement; be sure that the data types are compatible. Match each variable to
correspond to the columns positionally.
Alternatively, you can also define a record for the cursor and reference the record in the FETCH INTO clause.
Finally, test to see whether the cursor contains rows. If a fetch acquires no values, there are no rows left to
process in the active set and no error is recorded.
© [email protected] RDBMS Oracle / Page 103 of 125
RDBMS using Oracle
Closing the Cursor
The CLOSE statement disables the cursor, releases the context area, and "undefines" the active set. Close the
cursor after completing the processing of the FETCH statement. You can reopen the cursor if required. A
cursor can be reopened only if it is closed. If you attempt to fetch data from a cursor after it has been closed,
then an INVALID_CURSOR exception will be raised.
Syntax:
CLOSE cursor_name;
Note: Although it is possible to terminate the PL/SQL block without closing cursors, you should make it a
habit to close any cursor that you declare explicitly to free up resources. There is a maximum limit on the
number of open cursors per session, which is determined by the OPEN_CURSORS parameter in the database
parameter file. (OPEN_CURSORS = 50 by default.)
DECLARE DECLARE
CURSOR c_emp IS SELECT empno, sal FROM emp
CURSOR c_emp_cursor IS
WHERE deptno=20;
SELECT employee_id, last_name FROM employees ecode emp.empno%TYPE;
WHERE department_id =30; salary emp.sal%TYPE;
BEGIN
v_empno employees.employee_id%TYPE; OPEN c_emp;
v_lname employees.last_name%TYPE; IF c_emp%ISOPEN THEN
LOOP
BEGIN FETCH c_emp INTO ecode,salary;
OPEN c_emp_cursor; EXIT WHEN c_emp%NOTFOUND;
UPDATE emp SET sal=sal *1.1
LOOP
WHERE empno=ecode;
FETCH c_emp_cursor INTO v_empno, v_lname; INSERT INTO emp_raise
VALUES(ecode, sysdate,salary*.1);
EXIT WHEN c_emp_cursor%NOTFOUND;
END LOOP;
DBMS_OUTPUT.PUT_LINE( v_empno ||' COMMIT;
'||v_lname); CLOSE c_emp;
END LOOP; ELSE
DBMS_OUTPUT.PUT_LINE
END; ('Unable to open Cursor');
/ END IF;
END;
/
Cursors and Records
You can also define a record based on the selected list of columns in an explicit cursor. This is convenient for
processing the rows of the active set, because you can simply fetch into the record. Therefore, the values of
the row are loaded directly into the corresponding fields of the record.
DECLARE
CURSOR c_emp_cursor IS SELECT employee_id, last_name FROM employees WHERE department_id =30;
v_emp_record c_emp_cursor%ROWTYPE;
BEGIN
OPEN c_emp_cursor;
LOOP
FETCH c_emp_cursor INTO v_emp_record;
EXIT WHEN c_emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( v_emp_record.employee_id ||' '||v_emp_record.last_name);
END LOOP;
CLOSE c_emp_cursor;
END;
© [email protected] RDBMS Oracle / Page 104 of 125
RDBMS using Oracle
Cursor FOR Loops
You can use a cursor FOR loop, which processes rows in an explicit cursor. It is a shortcut because the cursor
is opened, a row is fetched once for each iteration in the loop, the loop exits when the last row is processed,
and the cursor is closed automatically. The loop itself is terminated automatically at the end of the iteration
where the last row is fetched.
In the syntax:
record_name Is the name of the implicitly declared record
cursor_name Is a PL/SQL identifier for the previously declared cursor
Do not declare the record that controls the loop; it is declared implicitly. Test the cursor attributes during
the loop, if required. Supplyy the parameters for a cursor, if required, in parentheses following the cursor
name in the FOR statement.
DECLARE DECLARE
CURSOR c_emp_cursor IS CURSOR c_emp IS SELECT empno,sal
SELECT employee_id, last_name FROM emp WHERE deptno=20;
FROM employees WHERE department_id =30; BEGIN
BEGIN FOR emp_rec IN c_emp LOOP
FOR emp_record IN c_emp_cursor
c_emp_curs UPDATE emp SET sal = emp_rec.sal * 1.05
LOOP WHERE empno=emp_rec.empno;
DBMS_OUTPUT.PUT_LINE( INSERT INTO emp_raise VALUES
emp_record.employee_id (emp_rec.empno,sysdate,emp_rec.sal*.05);
||' ' ||emp_record.last_name); END LOOP;
END LOOP; COMMIT;
END; END;
/ /

Explicit Cursor Attributes


As with implicit cursors, there are four attributes for obtaining status information about a cursor. When
appended to the cursor variable name, these attributes return useful information about the execution of a
cursor manipulation statement. You cannot reference
eference cursor attributes directly in a SQL statement.

© [email protected]
com BMS Oracle / Page 105 of 125
RDBM
RDBMS using Oracle
%ROWCOUNT and %NOTFOUND Example Using %ISOPEN Attribute Example
DECLARE …
CURSOR c_emp_cursor IS SELECT employee_id, IF NOT c_emp_cursor%ISOPEN THEN
last_name FROM employees; OPEN c_emp_cursor;
v_emp_record c_emp_cursor%ROWTYPE; END IF;
BEGIN LOOP
OPEN c_emp_cursor; FETCH c_emp_cursor
LOOP ...
FETCH c_emp_cursor INTO v_emp_record; Cursor FOR Loops Using Subqueries Example
EXIT WHEN c_emp_cursor%ROWCOUNT > 10 OR BEGIN
c_emp_cursor%NOTFOUND; FOR emp_record IN (SELECT employee_id,
DBMS_OUTPUT.PUT_LINE( last_name
FROM employees WHERE department_id =30)
v_emp_record.employee_id
||' '||v_emp_record.last_name); LOOP

END LOOP; DBMS_OUTPUT.PUT_LINE(


emp_record.employee_id
CLOSE c_emp_cursor;
||' '||emp_record.last_name);
END ;
END LOOP;
/
END;
/

Cursors with Parameters


You can pass parameters to a cursor. This means that you can open and close an explicit cursor several times
in a block, returning a different active set on each occasion. For each execution, the previous cursor is closed
and reopened with a new set of parameters.
Each formal parameter in the cursor declaration must have a corresponding actual parameter
in the OPEN statement. Parameter data types are the same as those for scalar variables, but
you do not give them sizes. The parameter names are for references in the query expression of the cursor.
Syntax:
DECLARE
CURSOR cursor_name [(parameter_name datatype, ...)] IS select_statement;


BEGIN
OPEN cursor_name(parameter_value,.....) ;

The parameter notation does not offer greater functionality; it simply allows you to specify input values
easily and clearly. This is particularly useful when the same cursor is referenced repeatedly.

© [email protected] RDBMS Oracle / Page 106 of 125


RDBMS using Oracle
Parameter data types are the same as those for scalar variables, but you do not give them sizes. The
parameter names are for reference in the cursor’s query. In the following example, a cursor
c is declared and
is defined with one parameter:
DECLARE
CURSOR emp_cursor (p_deptno NUMBER, p_job VARCHAR2) IS SELECT employee_id, last_name
FROM employees WHERE department_id = p_deptno AND job_id = p_job;
BEGIN
OPEN emp_cursor (80, ’SA_REP’);
...
CLOSE emp_cursor;
OPEN emp_cursor (60, ’IT_PROG’);
...
END;
Procedures and Functions
Until this point, anonymous blocks are the only examples of PL/SQL code covered in this course. As the name
indicates, anonymous blocks are unnamed executable PL/SQL blocks. Because they are unnamed, they can
be neither reused nor stored for later use.
Procedures
ocedures and functions are named PL/SQL blocks. They are also known as subprograms. These
subprograms are compiled and stored in the database. The block structure of the subprograms is similar to
the structure of anonymous blocks. Subprograms can be declared
declared not only at the schema level but also
within any other PL/SQL block. A subprogram contains the following sections:

• Declarative section: Subprograms can have an optional declarative section. However, unlike
anonymous blocks, the declarative section of a subprogram does not start with the DECLARE
keyword. The optional declarative section follows the IS or AS keyword in the subprogram
declaration.
• Executable section: This is the mandatory section of the subprogram, which contains the
implementation of the business
business logic. Looking at the code in this section, you can easily determine
the business functionality of the subprogram. This section begins and ends with the BEGIN and END
keywords, respectively.
• Exception section: This is an optional section that is included
included to handle exceptions.
Differences Between Anonymous Blocks and Subprograms

© [email protected]
com BMS Oracle / Page 107 of 125
RDBM
RDBMS using Oracle
Note: When you create any object (such as a table, procedure, function, and so on), the entries are made to
the user_objects table. When the code in the example is executed successfully, you can check the
user_objects table by issuing the following command:
SELECT object_name,object_type FROM user_objects;
Procedure Syntax :
CREATE [OR REPLACE] PROCEDURE procedure_name
[(argument1 [mode1] datatype1,
argument2 [mode2] datatype2,
. . .)]
IS|AS
procedure_body;
Example :
...
CREATE PROCEDURE add_dept IS
v_dept_id dept.department_id%TYPE;
v_dept_name dept.department_name%TYPE;
BEGIN
v_dept_id:=280;
v_dept_name:='ST-Curriculum';
INSERT INTO dept(department_id,department_name) VALUES(v_dept_id,v_dept_name);
DBMS_OUTPUT.PUT_LINE(' Inserted '|| SQL%ROWCOUNT ||' row ');
END;
Examine the code in the example. The add_dept procedure inserts a new department with department ID
280 and department name ST-Curriculum. The procedure declares two variables, dept_id and dept_name, in
the declarative section. The declarative section of a procedure starts immediately after the procedure
declaration and does not begin with the DECLARE keyword. The procedure uses the implicit cursor attribute
or the SQL%ROWCOUNT SQL attribute to verify whether the row was successfully inserted.
SQL%ROWCOUNT should return 1 in this case.
The source of the procedure is stored in the user_source table. You can check the source for the procedure
by issuing the following command:
SELECT * FROM user_source WHERE name='ADD_DEPT';
Invoking the Procedure
You have to include the call to the procedure in the executable section of the anonymous block. Similarly,
you can invoke the procedure from any application, such as a Forms application, a Java application, and so
on. The SELECT statement in the code checks to see whether the row was successfully inserted. You can also
invoke a procedure with the SQL statement CALL <procedure_name>.
BEGIN
add_dept;
END;
/
SELECT department_id, department_name FROM dept WHERE department_id=280;

© [email protected] RDBMS Oracle / Page 108 of 125


RDBMS using Oracle
Developing Procedures
To develop a stored procedure, perform the following steps:
1. Write the code to create a procedure in an editor or a word processor, and then save it as a SQL
script file (typically with an .sql extension).
2. Load the code into one of the development tools such as SQL*Plus.
3. Create the procedure in the database. The CREATE PROCEDURE statement compiles and stores
source code and the compiled m-code in the database. If compilation errors exist, then the m-code is
not stored and you must edit the source code to make corrections. You cannot invoke a procedure
that contains compilation errors. To view the compilation errors in SQL*Plus use:
1. SHOW ERRORS for the most recently (last) compiled procedure
2. SHOW ERRORS PROCEDURE procedure_name for any procedure compiled previously
4. After successful compilation, execute the procedure to perform the desired action. Use the EXECUTE
command from iSQL*Plus or an anonymous PL/SQL block from environments that support PL/SQL.
Note: If compilation errors occur, use a CREATE OR REPLACE PROCEDURE statement to overwrite the existing
code if you previously used a CREATE PROCEDURE statement. Otherwise, DROP the procedure first and then
execute the CREATE PROCEDURE statement.
What Are Parameters?
Parameters are used to transfer data values to and from the calling environment and the procedure (or
subprogram). Parameters are declared in the subprogram header, after the name and before the declaration
section for local variables. Parameters are subject to one of the three parameter-passing modes: IN, OUT, or
IN OUT.
1. An IN parameter passes a constant value from the calling environment into the procedure.
2. An OUT parameter passes a value from the procedure to the calling environment.
3. An IN OUT parameter passes a value from the calling environment to the procedure and a possibly
different value from the procedure back to the calling environment using the same parameter.
Parameters can be thought of as a special form of local variable, whose input values are initialized by the
calling environment when the subprogram is called, and whose output values are returned to the calling
environment when the subprogram returns control to the caller.
Formal and Actual Parameters
Formal parameters are local variables that are declared in the parameter list of a subprogram specification.
Example
CREATE PROCEDURE raise_sal(id NUMBER,sal NUMBER) IS
BEGIN ...
END raise_sal;
In the example above, the variable id and sal identifiers represent the formal parameters.
The actual parameters can be literal values, variables, and expressions that are provided in the parameter
list of a called subprogram.
emp_id := 100;
raise_sal(emp_id, 2000)
In the example above a call is made to raise_sal, where the emp_id variable provides the actual parameter
value for the id formal parameter and 2000 is supplied as the actual parameter value for sal. Actual
parameters are associated with formal parameters during the subprogram call.
The formal and actual parameters should be of compatible data types. If necessary, before assigning the
value, PL/SQL converts the data type of the actual parameter value to that of the formal parameter.
© [email protected] RDBMS Oracle / Page 109 of 125
RDBMS using Oracle
IN Parameter Example Calling with positional and named notation
CREATE OR REPLACE PROCEDURE CREATE OR REPLACE PROCEDURE add_dept(
raise_salary (id IN name IN departments.department_name%TYPE,
employees.employee_id%TYPE, loc IN departments.location_id%TYPE) IS
percent IN NUMBER) BEGIN
IS INSERT INTO departments(department_id,
BEGIN department_name, location_id)
UPDATE employees VALUES (departments_seq.NEXTVAL, name, loc);
SET salary = salary * END add_dept;
(1 + percent/100) /
WHERE employee_id = id; BEGIN
END raise_salary; add_dept ('TRAINING', 2500);
/ END;
In calling environment: /
BEGIN BEGIN
raise_salary(176,10); add_dept (loc=>2400, name=>'EDUCATION');
END; END;
/ /
OUT Parameter Example IN – OUT Parameter Example
CREATE OR REPLACE PROCEDURE CREATE OR REPLACE PROCEDURE format_phone
query_emp (id IN (phone_no IN OUT VARCHAR2) IS
employees.employee_id%TYPE, name OUT BEGIN
employees.last_name%TYPE, salary OUT phone_no := '(' || SUBSTR(phone_no,1,3) ||
employees.salary%TYPE) IS ')' || SUBSTR(phone_no,4,3) ||
BEGIN '-' || SUBSTR(phone_no,7);
SELECT last_name, salary INTO END format_phone;
name, salary FROM employees /
WHERE employee_id = id; BEGIN
END query_emp; phone_no ('8006330575');
/ END;
In calling environment: /
DECLARE
emp_name employees.last_name%TYPE;
emp_sal employees.salary%TYPE;
BEGIN
query_emp(171, emp_name, emp_sal); ...
END;
/

© [email protected] RDBMS Oracle / Page 110 of 125


RDBMS using Oracle
Using the DEFAULT Option for Parameters
CREATE OR REPLACE PROCEDURE add_dept( name departments.department_name%TYPE:='Unknown',
loc departments.location_id%TYPE DEFAULT 1700) IS
BEGIN
INSERT INTO departments (...) VALUES (departments_seq.NEXTVAL, name, loc);
END add_dept;
/
BEGIN
add_dept
add_dept ('ADVERTISING', loc => 1200)
add_dept (loc => 1200)
END;
/
The code examples above show two ways of assigning a default value to an IN parameter. The two ways
shown use:
• The assignment operator (:=), as shown for the name parameter
• The DEFAULT option, as shown for the loc parameter
When default values are assigned to formal parameters, you can call the procedure without supplying an
actual parameter value for the parameter. Thus, you can pass different numbers of actual parameters to a
subprogram, either by accepting or by overriding the default values as required. It is recommended that you
declare parameters without default values first. Then, you can add formal parameters with default values
without having to change every call to the procedure. You cannot assign default values to OUT and IN OUT
parameters.
The example above shows three ways of invoking the add_dept procedure:
• The first example assigns the default values for each parameter.
• The second example illustrates a combination of position and named notation to assign values. In
this case, using named notation is presented as an example.
• The last example uses the default value for the name parameter and the supplied value for the loc
parameter.
Usually, you can use named notation to override the default values of formal parameters. However, you
cannot skip providing an actual parameter if there is no default value provided for a formal parameter.
Note: All the positional parameters should precede the named parameters in a subprogram call. Otherwise,
you receive an error message, as shown in the following example:
BEGIN
add_dept(name=>'new dept', 'new location')
END;
/
The following error message generated;

© [email protected] RDBMS Oracle / Page 111 of 125


RDBMS using Oracle
Handled Exceptions
When you develop procedures that are called from other procedures, you should be aware of the effects
that handled and unhandled exceptions have on the transaction and the calling procedure. When an
exception is raised in a called procedure, the control immediately goes to the exception section of that
block. An exception is considered handled if the exception section provides a handler for the exception
raised. When an exception occurs and is handled, the following code flow takes place:
1. The exception is raised.
2. Control is transferred to the exception handler.
3. The block is terminated.
4. The calling program/block continues to execute as if nothing has happened.
If a transaction was started (that is, if any data manipulation language [DML] statements executed before
executing the procedure in which the exception was raised), then the transaction is unaffected. A DML
operation is rolled back if it was performed within the procedure before the exception. You can explicitly end
a transaction by executing a COMMIT or ROLLBACK operation in the exception section.

Example:
CREATE PROCEDURE add_department(name VARCHAR2, mgr NUMBER, loc NUMBER) IS
BEGIN
INSERT INTO DEPARTMENTS (department_id, department_name, manager_id, location_id)
VALUES (DEPARTMENTS_SEQ.NEXTVAL, name, mgr, loc);
DBMS_OUTPUT.PUT_LINE('Added Dept: '||name);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Err: adding dept: '||name);
END;
/
CREATE PROCEDURE create_departments IS
BEGIN
add_department('Media', 100, 1800); 
add_department('Editing', 99, 1800); 
add_department('Advertising', 101, 1800); 
END;
/
The Editing department with manager_id of 99 is not inserted because of a foreign key integrity constraint
violation on the manager_id.
Removing Procedures
When a stored procedure is no longer required, you can use the DROP PROCEDURE SQL statement to
remove it.
DROP PROCEDURE procedurename;

© [email protected] RDBMS Oracle / Page 112 of 125


RDBMS using Oracle
Stored Functions
A function is a named PL/SQL block that can accept parameters, be invoked, and return a value. In general,
you use a function to compute a value. Functions and procedures are structured alike. A function must
return a value to the calling environment, whereas a procedure returns zero or more values to its calling
environment. Like a procedure, a function has a header, a declarative section, an executable section, and an
optional exception-handling section. A function must have a RETURN clause in the header and at least one
RETURN statement in the executable section.
Functions can be stored in the database as schema objects for repeated execution. A function that is stored
in the database is referred to as a stored function. Functions can also be created on client-side applications.
Functions promote reusability and maintainability. When validated, they can be used in any number of
applications. If the processing requirements change, only the function needs to be updated.
A function may also be called as part of a SQL expression or as part of a PL/SQL expression. In the context of
a SQL expression, a function must obey specific rules to control side effects. In a PL/SQL expression, the
function identifier acts like a variable whose value depends on the parameters passed to it.
Syntax:
CREATE [OR REPLACE] FUNCTION function_name [(parameter1 [mode1] datatype1, ...)]
RETURN datatype IS|AS
[local_variable_declarations; …]
BEGIN
-- actions;
RETURN expression;
END [function_name];
You should consider the following points about the CREATE FUNCTION statement:
1. The REPLACE option indicates that if the function exists, it is dropped and replaced with the new
version that is created by the statement.
2. The RETURN data type must not include a size specification.
3. The PL/SQL block starts with a BEGIN after the declaration of any local variables and ends with an
END, optionally followed by the function_name.
4. There must be at least one RETURN expression statement.
5. You cannot reference host or bind variables in the PL/SQL block of a stored function.
Example:
CREATE OR REPLACE FUNCTION get_sal (id employees.employee_id%TYPE)
RETURN NUMBER IS
sal employees.salary%TYPE := 0;
BEGIN
SELECT salary INTO sal FROM employees WHERE employee_id = id;
RETURN sal;
END get_sal;
/
Invoking function in calling environment
BEGIN
dbms_output.put_line( get_sal(100) );
END;
Here get_sal function is invoked first to calculate the salary of the employee with ID 100. The salary value
returned is supplied as the value of the DBMS_OUTPUT.PUT_LINE parameter, which displays the result.

© [email protected] RDBMS Oracle / Page 113 of 125


RDBMS using Oracle
More Function Example:
CREATE FUNCTION check_sal RETURN Boolean IS
v_dept_id employees.department_id%TYPE;
v_empno employees.employee_id%TYPE;
v_sal employees.salary%TYPE;
v_avg_sal employees.salary%TYPE;
BEGIN
v_empno:=205;
SELECT salary,department_id INTO v_sal,v_dept_id FROM employees
WHERE employee_id= v_empno;
SELECT avg(salary) INTO v_avg_sal FROM employees WHERE department_id=v_dept_id;
IF v_sal > v_avg_sal THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL;
END;
/
Invoking Function
BEGIN
IF (check_sal IS NULL) THEN
DBMS_OUTPUT.PUT_LINE('The function returned NULL due to exception');
ELSIF (check_sal) THEN
DBMS_OUTPUT.PUT_LINE('Salary > average');
ELSE
DBMS_OUTPUT.PUT_LINE('Salary < average');
END IF;
END;
/
Ways to Execute Functions
If functions are designed thoughtfully, they can be powerful constructs. Functions can be invoked in the
following ways:
• As part of PL/SQL expressions: You can use local variables to hold the returned value from a
function.
DECLARE
sal employees.salary%type;
BEGIN
sal := get_sal(100);
END;
The example above uses a local variable in an anonymous block.
• As a parameter to another subprogram: The example below demonstrates that the get_sal function
with all its arguments is nested in the parameter required by the DBMS_OUTPUT.PUT_LINE
procedure.
dbms_output.put_line(get_sal(100));
• As an expression in a SQL statement: The example below shows how a function can be used as a
single-row function in a SQL statement.
SELECT job_id, get_sal(employee_id) FROM employees;

© [email protected] RDBMS Oracle / Page 114 of 125


RDBMS using Oracle
Advantages of User-Defined Functions in SQL Statements
SQL statements can reference PL/SQL user-defined functions anywhere a SQL expression is allowed. For
example, a user-defined function can be used anywhere that a built-in SQL function, such as UPPER(), can be
placed. Following is the list of advantages:
• Permits calculations that are too complex, awkward, or unavailable with SQL.
• Increases data independence by processing complex data analysis within the Oracle server, rather
than by retrieving the data into an application.
• Increases efficiency of queries by performing functions in the query rather than in the application.
• Manipulates new types of data (for example, latitude and longitude) by encoding character strings
and using functions to operate on the strings.
Function in SQL Expressions:
The example below shows how to create a tax function to calculate income tax. The function accepts a
NUMBER parameter and returns the calculated income tax based on a simple flat tax rate of 8%.
CREATE OR REPLACE FUNCTION tax(value IN NUMBER)
RETURN NUMBER IS
BEGIN
RETURN (value * 0.08);
END tax;
/
SELECT employee_id, last_name, salary, tax(salary) FROM employees WHERE department_id = 100;
In SQL*Plus, the tax function is invoked as an expression in the SELECT clause along with the employee ID,
last name, and salary for employees in a department with ID 100. The return result from the tax function is
displayed with the regular output from the query.
Removing Functions
When a stored function is no longer required, you can use a SQL statement in SQL*Plus to drop it. To remove
a stored function by using SQL*Plus, execute the DROP FUNCTION SQL command.
DROP FUNCTION functionname;
How Procedures and Functions Differ
You create a procedure to store a series of actions for later execution. A procedure can contain zero or more
parameters that can be transferred to and from the calling environment, but a procedure does not have to
return a value. A procedure can call a function to assist with its actions.

A procedure containing a single OUT parameter would be better rewritten as a function returning the value.
You create a function when you want to compute a value that must be returned to the calling environment.
A function can contain zero or more parameters that are transferred from the calling environment.
Functions typically return only a single value, and the value is returned through a RETURN statement. The
functions used in SQL statements should not use OUT or IN OUT mode parameters. Although a function
using output parameters can be used in a PL/SQL procedure or block, it cannot be used in SQL statements.

© [email protected] RDBMS Oracle / Page 115 of 125


RDBMS using Oracle
PL/SQL Packages: Overview
PL/SQL packages enable you to bundle related PL/SQL types, variables, data structures, exceptions, and
subprograms into one container. For example, a Human Resources package can contain hiring and firing
procedures, commission and bonus functions, and tax exemption variables. A package usually consists of
two parts stored separately in the database:

• A specification
• A body (optional)
The package itself cannot be called, parameterized, or nested. After writing and compiling, the contents can
be shared with many applications. When a PL/SQL-packaged construct is referenced for the first time, the
whole package is loaded into memory. Subsequent access to constructs in the same package do not require
disk input/output (I/O).
Components of a PL/SQL Package
You create a package in two parts:
The package specification is the interface to your applications. It declares the public types, variables,
constants, exceptions, cursors, and subprograms available for use. The package specification may also
include PRAGMAs, which are directives to the compiler.
The package body defines its own subprograms and must fully implement subprograms declared in the
specification part. The package body may also define PL/SQL constructs, such as types, variables, constants,
exceptions, and cursors.
Public components are declared in the package specification. The specification defines a public application
programming interface (API) for users of package features and functionality—that is, public components can
be referenced from any Oracle server environment that is external to the package.
Private components are placed in the package body and can be referenced only by other constructs within
the same package body. Private components can reference the package public components.
Note: If a package specification does not contain subprogram declarations, then there is no requirement for
a package body.
Developing PL/SQL Packages
To develop a package, perform the following steps:
1. Edit the text for the specification by using the CREATE PACKAGE statement within a SQL script file.
Edit the text for the body by using the CREATE PACKAGE BODY statement within a SQL script file.
2. Load the script files into a tool such as SQL*Plus.
3. Execute the script files to create (that is, to compile and store) the package and package body in the
database.
4. Execute any public construct within the package specification from an Oracle server environment.
The Oracle server stores the specification and body of a package separately. This enables you to change the
implementation of a program construct in the package body without invalidating other schema objects that
call or reference the program construct.
Creating the Package Specification
To create packages, you declare all public constructs within the package specification. Specify the OR
REPLACE option, if overwriting an existing package specification. Initialize a variable with a constant value or
formula within the declaration, if required; otherwise, the variable is initialized implicitly to NULL.

© [email protected] RDBMS Oracle / Page 116 of 125


RDBMS using Oracle
Syntax:
CREATE [OR REPLACE] PACKAGE package_name IS|AS
public type and variable declarations
subprogram specifications
END [package_name];
The following are definitions of items in the package syntax:

• package_name specifies a name for the package that must be unique among objects within the
owning schema. Including the package name after the END keyword is optional.
• public type and variable declarations declares public variables, constants, cursors, exceptions, user-
defined types, and subtypes.
• subprogram specification specifies the public procedure or function declarations.
Example:
CREATE OR REPLACE PACKAGE comm_pkg IS
std_comm NUMBER := 0.10;
PROCEDURE reset_comm(new_comm NUMBER);
END comm_pkg;
/
The example above creates a package called comm_pkg used to manage business processing rules for
commission calculations.
The std_comm public (global) variable is declared to hold a maximum allowable percentage commission for
the user session, and it is initialized to 0.10 (that is, 10%).
The reset_comm public procedure is declared to accept a new commission percentage that updates the
standard commission percentage if the commission validation rules are accepted. The validation rules for
resetting the commission are not made public and do not appear in the package specification. The validation
rules are managed by using a private function in the package body.
Creating the Package Body
Create a package body to define and implement all public subprograms and supporting private constructs.
When creating a package body, perform the following steps:
• Specify the OR REPLACE option to overwrite an existing package body.
• Define the subprograms in an appropriate order. The basic principle is that you must declare a
variable or subprogram before it can be referenced by other components in the same package body.
It is common to see all private variables and subprograms defined first and the public subprograms
defined last in the package body.
• Complete the implementation for all procedures or functions declared in the package specification
within the package body.
Syntax:
CREATE [OR REPLACE] PACKAGE BODY package_name IS|AS
private type and variable declarations
subprogram bodies
[BEGIN initialization statements]
END [package_name];
The following are definitions of items in the package body syntax:
• package_name specifies a name for the package that must be the same as its package specification.
Using the package name after the END keyword is optional.

© [email protected] RDBMS Oracle / Page 117 of 125


RDBMS using Oracle
• private type and variable declarations declares private variables, constants, cursors, exceptions,
user-defined types, and subtypes.
• subprogram specification specifies the full implementation of any private and/or public procedures
or functions.
• [BEGIN initialization statements] is an optional block of initialization code that executes when the
package is first referenced.
Example:
CREATE OR REPLACE PACKAGE BODY comm_pkg IS
FUNCTION validate(comm NUMBER) RETURN BOOLEAN IS
max_comm employees.commission_pct%type;
BEGIN
SELECT MAX(commission_pct) INTO max_comm FROM employees;
RETURN (comm BETWEEN 0.0 AND max_comm);
END validate;
PROCEDURE reset_comm (new_comm NUMBER) IS BEGIN
IF validate(new_comm) THEN
std_comm := new_comm; -- reset public var
ELSE
RAISE_APPLICATION_ERROR(-20210, 'Bad Commission');
END IF;
END reset_comm;
END comm_pkg;
/
The example above shows the complete package body for comm_pkg, with a private function called validate
to check for a valid commission. The validation requires that the commission be positive and lesser than the
highest commission among existing employees. The reset_comm procedure invokes the private validation
function before changing the standard commission in std_comm.
Invoking Package Subprograms
After the package is stored in the database, you can invoke public or private subprograms within the same
package, or public subprograms if external to the package. Fully qualify the subprogram with its package
name when invoked externally from the package. Use the package_name.subprogram syntax.
Example:
A package procedure from SQL*Plus:
comm_pkg.reset_comm(0.15);
Invoke a package procedure in a different schema:
scott.comm_pkg.reset_comm(0.15);
Removing Packages
When a package is no longer required, you can use a SQL statement in SQL*Plus to remove it. A package has
two parts; therefore, you can remove the whole package, or you can remove only the package body and
retain the package specification.
DROP PACKAGE package_name;
DROP PACKAGE BODY package_name;

© [email protected] RDBMS Oracle / Page 118 of 125


RDBMS using Oracle
TRIGGERS
A trigger is a PL/SQL block or a PL/SQL procedure associated with a table, view, schema, or database which
executes implicitly whenever a particular event takes place. There can be either of the following:
• Application trigger: Fires whenever an event occurs with a particular application
• Database trigger: Fires whenever a data event (such as DML) or system event (such as logon or
shutdown) occurs on a schema or database
Application triggers execute implicitly whenever a particular data manipulation language (DML) event occurs
within an application. An example of an application that uses triggers extensively is an application developed
with Oracle Forms Developer.
Database triggers execute implicitly when any of the following events occur:
• DML operations on a table
• DML operations on a view, with an INSTEAD OF trigger
• DDL statements, such as CREATE and ALTER
This is the case no matter which user is connected or which application is used. Database triggers also
execute implicitly when some user actions or database system actions occur (for example, when a user logs
on or the DBA shuts down the database).
Database triggers can be defined on tables and on views. If a DML operation is issued on a view, then the
INSTEAD OF trigger defines what actions take place. If these actions include DML operations on tables, then
any triggers on the base tables are fired.
Database triggers can be system triggers on a database or a schema. For databases, triggers fire for each
event for all users; for a schema, they fire for each event for that specific user.
You can design triggers to:
• Use triggers to guarantee that related actions are performed for a specific operation.
• Use database triggers for centralized, global operations that should be fired for the triggering
statement, independent of the user or application issuing the statement.
• Do not define triggers to duplicate or replace the functionality already built into the Oracle database.
For example, implement integrity rules using declarative constraints, not triggers. To remember the
design order for a business rule:
o Use built-in constraints in the Oracle server, such as primary key, and so on.
o Develop a database trigger or an application, such as a servlet or Enterprise JavaBeans (EJB)
on your middle tier.
o Use a presentation interface, such as Oracle Forms, HTML, JavaServer Pages (JSP) and so on,
for data presentation rules.
• Excessive use of triggers can result in complex interdependencies, which may be difficult to
maintain. Use triggers when necessary, and be aware of recursive and cascading effects.
• Avoid lengthy trigger logic by creating stored procedures or packaged procedures that are invoked in
the trigger body.
• Database triggers fire for every user each time the event occurs on the trigger that is created.
Creating DML Triggers
A statement trigger fires once for a DML statement. A row trigger fires once for each row affected. Trigger
names must be unique with respect to other triggers in the same schema.
The trigger type determines whether the body executes for each row or only once for the triggering
statement.

© [email protected] RDBMS Oracle / Page 119 of 125


RDBMS using Oracle
• A statement trigger:
o Executes once for the triggering event
o Is the default type of trigger
o Fires once even if no rows are affected at all
• A row trigger:
o Executes once for each row affected by the triggering event
o Is not executed if the triggering event does not affect any rows
o Is indicated by specifying the FOR EACH ROW clause
Syntax:
CREATE [OR REPLACE] TRIGGER trigger_name
timing
event1 [OR event2 OR event3]
ON object_name
[[REFERENCING OLD AS old | NEW AS new]
FOR EACH ROW
[WHEN (condition)]]
trigger_body
The components of the trigger syntax are:
• trigger_name uniquely identifies the trigger.
• timing indicates when the trigger fires in relation to the triggering event. Values are BEFORE, AFTER,
and INSTEAD OF.
• event identifies the DML operation causing the trigger to fire.
Values are INSERT, UPDATE [OF column], and DELETE.
• object_name indicates the table or view associated with the trigger.
• For row triggers, you can specify:
o A REFERENCING clause to choose correlation names for referencing the old and new values
of the current row (default values are OLD and NEW)
o FOR EACH ROW to designate that the trigger is a row trigger
o A WHEN clause to apply a conditional predicate, in parentheses, which is evaluated for each
row to determine whether or not to execute the trigger body
• The trigger_body is the action performed by the trigger, implemented as either of the following:
o An anonymous block with a DECLARE or BEGIN, and an END
o A CALL clause to invoke a stand-alone or packaged stored procedure, such as:
CALL my_procedure;
Trigger Timing
The BEFORE trigger timing is frequently used in the following situations:
• To determine whether the triggering statement should be allowed to complete (This eliminates
unnecessary processing and enables a rollback in cases where an exception is raised in the triggering
action.)
• To derive column values before completing an INSERT or UPDATE statement
• To initialize global variables or flags, and to validate complex business rules

© [email protected] RDBMS Oracle / Page 120 of 125


RDBMS using Oracle
The AFTER triggers are frequently used in the following situations:
• To complete the triggering statement before
before executing the triggering action
• To perform different actions on the same triggering statement if a BEFORE trigger is already present
The INSTEAD OF triggers provide a transparent way of modifying views that cannot be modified directly
through SQL DML statements
tements because a view is not always modifiable. You can write appropriate DML
statements inside the body of an INSTEAD OF trigger to perform actions directly on the underlying tables of
views.
If multiple triggers are defined for a table, then the order in
in which multiple triggers of the same type fire is
arbitrary. To ensure that triggers of the same type are fired in a particular order, consolidate the triggers into
one trigger that calls separate procedures in the desired order.
Trigger-Firing Sequence
Create
reate a statement trigger or a row trigger based on the requirement that the trigger must fire once for each
row affected by the triggering statement, or just once for the triggering statement, regardless of the number
of rows affected. When the triggering DML statement affects a single row, both the statement trigger and
the row trigger fire exactly once.
Example
The SQL statement in the example does not differentiate statement triggers from row triggers because
exactly one row is inserted into the table using
using the syntax for the INSERT statement shown in the example.
INSERT INTO departments (department_id,department_name, location_id)
VALUES (400, 'CONSULTING', 2400);

When the triggering DML statement affects many rows, the statement trigger fires exactly once, and the row
trigger fires once for every row affected by the statement.
UPDATE employees SET salary = salary * 1.1 WHERE department_id = 30;

The SQL statement in the example causes a row-levellevel trigger to fire a number of times equal to the number
numbe
of rows that satisfy the WHERE clause (that is, the number of employees reporting to department 30).

© [email protected]
com BMS Oracle / Page 121 of 125
RDBM
RDBMS using Oracle
Triggering Event Types
The triggering event or statement can be an INSERT, UPDATE, or DELETE statement on a table. When the
triggering event is an UPDATE statement, you can include a column list to identify which columns must be
changed to fire the trigger. You cannot specify a column list for an INSERT or for a DELETE statement because
it always affects entire rows.
. . . UPDATE OF salary . . .
The triggering event can contain one, two, or all three of these DML operations.
. . . INSERT or UPDATE or DELETE
. . . INSERT or UPDATE OF job_id . . .
The trigger body defines the action—that is, what needs to be done when the triggering event is issued. The
PL/SQL block can contain SQL and PL/SQL statements, and can define PL/SQL constructs such as variables,
cursors, exceptions, and so on. You can also call a PL/SQL procedure or a Java procedure. The size of a trigger
cannot be greater than 32 KB.
Creating a DML Statement Trigger
In the example below, the SECURE_EMP database trigger is a BEFORE statement trigger that prevents the
INSERT operation from succeeding if the business condition is violated. In this case, the trigger restricts
inserts into the EMPLOYEES table during certain business hours, Monday through Friday.
If a user attempts to insert a row into the EMPLOYEES table on Saturday, then the user sees an error
message, the trigger fails, and the triggering statement is rolled back. Remember that the
RAISE_APPLICATION_ERROR is a server-side built-in procedure that returns an error to the user and causes
the PL/SQL block to fail. When a database trigger fails, the triggering statement is automatically rolled back
by the Oracle server.
CREATE OR REPLACE TRIGGER secure_emp
BEFORE INSERT ON employees BEGIN
IF (TO_CHAR(SYSDATE,'DY') IN ('SAT','SUN')) OR (TO_CHAR(SYSDATE,'HH24:MI')
NOT BETWEEN '08:00' AND '18:00') THEN
RAISE_APPLICATION_ERROR(-20500, 'You may insert into EMPLOYEES table only during '
||' business hours.');
END IF;
END;
/
Combining Triggering Events
You can combine several triggering events into one by taking advantage of the special conditional predicates
INSERTING, UPDATING, and DELETING within the trigger body.
Example
Create one trigger to restrict all data manipulation events on the EMPLOYEES table to certain business hours,
Monday through Friday.
CREATE OR REPLACE TRIGGER secure_emp
BEFORE INSERT OR UPDATE OR DELETE
ON employees
BEGIN
IF (TO_CHAR(SYSDATE,'DY') IN ('SAT','SUN')) OR (TO_CHAR(SYSDATE,'HH24')
NOT BETWEEN '08' AND '18') THEN
IF DELETING THEN
RAISE_APPLICATION_ERROR(-20502,'You may delete from EMPLOYEES'
© [email protected] RDBMS Oracle / Page 122 of 125
RDBMS using Oracle
|| ' table only during business hours.');
ELSIF INSERTING THEN
RAISE_APPLICATION_ERROR(-20500,'You may insert into EMPLOYEES table'
|| ' only during business hours.');
ELSIF UPDATING('SALARY') THEN
RAISE_APPLICATION_ERROR(-20503, 'You may '
|| 'update SALARY only during business hours.');
ELSE
RAISE_APPLICATION_ERROR(-20504,'You may'
|| ' update EMPLOYEES table only during normal hours.');
END IF;
END IF;
END;
/
Creating a DML Row Trigger
You can create a BEFORE row trigger in order to prevent the triggering operation from succeeding if a certain
condition is violated. In the example below, a trigger is created to allow certain employees to be able to earn
a salary of more than 15,000.
CREATE OR REPLACE TRIGGER restrict_salary
BEFORE INSERT OR UPDATE OF salary ON employees
FOR EACH ROW
BEGIN
IF NOT (:NEW.job_id IN ('AD_PRES', 'AD_VP')) AND :NEW.salary > 15000 THEN
RAISE_APPLICATION_ERROR (-20202, 'Employee cannot earn more than $15,000.');
END IF;
END;
/
Using OLD and NEW Qualifiers
Within a ROW trigger, reference the value of a column before and after the data change by prefixing it with
the OLD and NEW qualifiers.

Data Operation Old Value New Value


INSERT NULL Inserted value
UPDATE Value before update Value after update
DELETE Value before delete NULL
The OLD and NEW qualifiers are available only in ROW triggers. Prefix these qualifiers with a colon (:) in
every SQL and PL/SQL statement. There is no colon (:) prefix if the qualifiers are referenced in the WHEN
restricting condition. Row triggers can decrease the performance if you perform many updates on larger
tables.
Example:
CREATE OR REPLACE TRIGGER audit_emp_values
AFTER DELETE OR INSERT OR UPDATE ON employees
FOR EACH ROW
BEGIN
INSERT INTO audit_emp(user_name, time_stamp, id, old_last_name, new_last_name, old_title,
new_title, old_salary, new_salary) VALUES (USER, SYSDATE, :OLD.employee_id,
:OLD.last_name, :NEW.last_name, :OLD.job_id,
:NEW.job_id, :OLD.salary, :NEW.salary);
END;
/

© [email protected] RDBMS Oracle / Page 123 of 125


RDBMS using Oracle
Restricting a Row Trigger:
To restrict the trigger action to those rows that satisfy a certain condition, provide a WHEN clause. Create a
trigger on the EMPLOYEES table to calculate an employee’s commission when a row is added to the
EMPLOYEES table, or when an employee’s salary is modified. The NEW qualifier cannot be prefixed with a
colon in the WHEN clause because the WHEN clause is outside the PL/SQL blocks.
CREATE OR REPLACE TRIGGER derive_commission_pct
BEFORE INSERT OR UPDATE OF salary ON employees
FOR EACH ROW
WHEN (NEW.job_id = 'SA_REP')
BEGIN
IF INSERTING THEN
:NEW.commission_pct := 0;
ELSIF :OLD.commission_pct IS NULL THEN
:NEW.commission_pct := 0;
ELSE
:NEW.commission_pct := :OLD.commission_pct+0.05;
END IF;
END;
/
Implementing an Integrity Constraint with a Trigger
The example given below explains a situation in which the integrity constraint can be taken care of by using a
trigger. The EMPLOYEES table has a foreign key constraint on the DEPARTMENT_ID column of the
DEPARTMENTS table.
UPDATE employees SET department_id = 999 WHERE employee_id = 170;
-- Integrity constraint violation error
In the SQL statement above, the DEPARTMENT_ID of the employee 170 is not modified to 999. Because
department 999 does not exist in the DEPARTMENTS table, the statement raises exception –2292 for the
integrity constraint violation.
Now create following trigger :
CREATE OR REPLACE TRIGGER employee_dept_fk_trg
AFTER UPDATE OF department_id ON employees FOR EACH ROW
BEGIN
INSERT INTO departments VALUES(:new.department_id, 'Dept '||:new.department_id, NULL, NULL);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
NULL; -- mask exception if department exists
END;
/
The EMPLOYEE_DEPT_FK_TRG trigger is created that inserts a new row into the DEPARTMENTS table, using
:NEW.DEPARTMENT_ID for the value of the new department’s DEPARTMENT_ID. The trigger fires when the
UPDATE statement modifies the DEPARTMENT_ID of employee 170 to 999. When the foreign key constraint
is checked, it is successful because the trigger inserted the department 999 into the DEPARTMENTS table.
Therefore, no exception occurs unless the department already exists when the trigger attempts to insert the
new row. However, the EXCEPTION handler traps and masks the exception allowing the operation to
succeed.
Now apply following command:
UPDATE employees SET department_id = 999 WHERE employee_id = 170;
-- Successful after trigger is fired
Likewise you can handle Implementation of an Integrity constraint with a trigger.
© [email protected] RDBMS Oracle / Page 124 of 125
RDBMS using Oracle
Generating Primary Key Value using Trigger
Consider a table Client_Master having Client_no as Primary Key column. Create following trigger to generate
primary key value automatically.
CREATE OR REPLACE TRIGGER clno_gen
BEFORE INSERT ON client_master FOR EACH ROW
DECLARE
max_ckey_value VARCHAR2(5);
new_ckey_value VARCHAR2(5);
BEGIN
SELECT NVL ( SUBSTR ( MAX ( client_no ) , 2 , 5 ) , 0 )
INTO max_ckey_value FROM client_master;
new_ckey_value := LPAD ( TO_CHAR ( ( TO_NUMBER ( max_ckey_value ) + 1 ) ) , 5 , '0' );
:new.client_no := 'C' || new_ckey_value;
END;
/
Disable or reenable a database trigger:
ALTER TRIGGER trigger_name DISABLE | ENABLE
Disable or reenable all triggers for a table:
ALTER TABLE table_name DISABLE | ENABLE ALL TRIGGERS
Recompile a trigger for a table:
ALTER TRIGGER trigger_name COMPILE
To remove a trigger from the database, use the DROP TRIGGER statement:
DROP TRIGGER trigger_name;
Example:
DROP TRIGGER secure_emp;
Note: All triggers on a table are removed when the table is removed.



© [email protected] RDBMS Oracle / Page 125 of 125

You might also like