Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
24 views

SQL & PLSQL - Ebook

Uploaded by

sai man
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views

SQL & PLSQL - Ebook

Uploaded by

sai man
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

Contents

1. SQL { Structured Query Language


1.1. Tables 1
Oracle/SQL Tutorial1 1.2. Queries (Part I) 3
1.3. Data De nition in SQL 6
Michael Gertz 1.4. Data Modi cations in SQL 9
Database and Information Systems Group 1.5. Queries (Part II) 11
Department of Computer Science 1.6. Views 19
University of California, Davis 2. SQL*Plus (Minimal User Guide, Editor Commands, Help System) 20
gertz@cs.ucdavis.edu
http://www.db.cs.ucdavis.edu 3. Oracle Data Dictionary 23
4. Application Programming
4.1. PL/SQL
4.1.1 Introduction 26
4.1.2 Structure of PL/SQL Blocks 27
This Oracle/SQL tutorial provides a detailed introduction to the SQL query language and the 4.1.3 Declarations 27
Oracle Relational Database Management System. Further information about Oracle and SQL 4.1.4 Language Elements 28
can be found on the web site www.db.cs.ucdavis.edu/dbs. 4.1.5 Exception Handling 32
4.1.6 Procedures and Functions 34
Comments, corrections, or additions to these notes are welcome. Many thanks to Christina 4.1.7 Packages 36
Chung for comments on the previous version. 4.1.8 Programming in PL/SQL 38
4.2. Embedded SQL and Pro*C 39
5. Integrity Constraints and Triggers
Recommended Literature 5.1. Integrity Constraints
George Koch and Kevin Loney: Oracle8 The Complete Reference (The Single Most Compre- 5.1.1 Check Constraints 46
hensive Sourcebook for Oracle Server, Includes CD with electronic version of the book), 1299 5.1.2 Foreign Key Constraints 47
pages, McGraw-Hill/Osborne, 1997. 5.1.3 More About Column- and Table Constraints 49
Michael Abbey and Michael Corey: Oracle8 : A Beginner's Guide [A Thorough Introduction 5.2. Triggers
5.2.1 Overview 50
for First-time Users], 767 pages, McGraw-Hill/Osborne, 1997. 5.2.2 Structure of Triggers 50
Steven Feuerstein, Bill Pribyl, Debby Russell: Oracle PL/SQL Programming (2nd Edition), 5.2.3 Example Triggers 53
O'Reilly & Associates, 1028 pages, 1997. 5.2.4 Programming Triggers 55
C.J. Date and Hugh Darwen: A Guide to the SQL Standard (4th Edition), Addison-Wesley, 6. System Architecture
1997. 6.1. Storage Management and Processes 58
Jim Melton and Alan R. Simon: Understanding the New SQL: A Complete Guide (2nd Edition, 6.2. Logical Database Structures 60
Dec 2000), The Morgan Kaufmann Series in Data Management Systems, 2000. 6.3. Physical Database Structures 61
6.4. Steps in Processing an SQL Statement 63
1 revised Version 1.01, January 2000, Michael Gertz, Copyright 2000.
6.5. Creating Database Objects 63
1 SQL { Structured Query Language  long: Character data up to a length of 2GB. Only one long column is allowed per table.

1.1 Tables Note: In Oracle-SQL there is no data type boolean. It can, however, be simulated by using
either char(1) or number(1).
In relational database systems (DBS) data are represented using tables (relations ). A query As long as no constraint restricts the possible values of an attribute, it may have the special
issued against the DBS also results in a table. A table has the following structure: value null (for unknown). This value is di erent from the number 0, and it is also di erent
from the empty string ''.
Column 1 Column 2 : : : Column n Further properties of tables are:
, Tuple (or Record)  the order in which tuples appear in a table is not relevant (unless a query requires an
::: ::: ::: ::: explicit sorting).
 a table has no duplicate tuples (depending on the query, however, duplicate tuples can
A table is uniquely identi ed by its name and consists of rows that contain the stored informa- appear in the query result).
tion, 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 A database schema is a set of relation schemas. The extension of a database schema at database
tuples. The structure of a table, also called relation schema, thus is de ned by its attributes. run-time is called a database instance or database, for short.
The type of information to be stored in a table is de ned by the data types of the attributes
at table creation time.
1.1.1 Example Database
SQL uses the terms table, row, and column for relation, tuple, and attribute, respectively. In
this tutorial we will use the terms interchangeably. In the following discussions and examples we use an example database to manage information
A table can have up to 254 columns which may have di erent or same data types and sets of about employees, departments and salary scales. The corresponding tables can be created
values (domains), respectively. Possible domains are alphanumeric data (strings), numbers and under the UNIX shell using the command demobld. The tables can be dropped by issuing
date formats. Oracle o ers the following basic data types: the command demodrop under the UNIX shell.
The table EMP is used to store information about employees:
 char(n): Fixed-length character data (string), n characters long. The maximum size for EMPNO ENAME JOB MGR HIREDATE SAL DEPTNO
n is 255 bytes (2000 in Oracle8). Note that a string of type char is always padded on 7369 SMITH CLERK 7902 17-DEC-80 800 20
right with blanks to full length of n. (☞ can be memory consuming). 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 30
Example: char(40) 7521 WARD SALESMAN 7698 22-FEB-81 1250 30
...........................................................
 varchar2(n): Variable-length character string. The maximum size for n is 2000 (4000 in 7698 BLAKE MANAGER 01-MAY-81 3850 30
Oracle8). Only the bytes used for a string require storage. Example: varchar2(80) 7902 FORD ANALYST 7566 03-DEC-81 3000 10
 number(o; d): Numeric data type for integers and reals. o = overall number of digits, d For the attributes, the following data types are de ned:
= number of digits to the right of the decimal point.
Maximum values: o =38, d= ,84 to +127. Examples: number(8), number(5,2) EMPNO:number(4), ENAME:varchar2(30), JOB:char(10), MGR:number(4),
Note that, e.g., number(5,2) cannot contain anything larger than 999.99 without result- HIREDATE:date, SAL:number(7,2), DEPTNO:number(2)
ing in an error. Data types derived from number are int[eger], dec[imal], smallint Each row (tuple) from the table is interpreted as follows: an employee has a number, a name,
and real. a job title and a salary. Furthermore, for each employee the number of his/her manager, the
 date: Date data type for storing date and time. date he/she was hired, and the number of the department where he/she is working are stored.
The default format for a date is: DD-MMM-YY. Examples: '13-OCT-94', '07-JAN-98'
1 2
The table DEPT stores information about departments (number, name, and location): For the di erent data types supported in Oracle, several operators and functions are provided:
DEPTNO DNAME LOC  for numbers: abs, cos, sin, exp, log, power, mod, sqrt, +; ,; ; =, : : :
10 STORE CHICAGO
20 RESEARCH DALLAS  for strings: chr, concat(string1, string2), lower, upper, replace(string, searchstring,
30 SALES NEW YORK replacement string), translate, substr(string, m, n), length, to date, : : :
40 MARKETING BOSTON
 for the date data type: add month, month between, next day, to char, : : :
Finally, the table SALGRADE contains all information about the salary scales, more precisely, the
maximum and minimum salary of each scale. The usage of these operations is described in detail in the SQL*Plus help system (see also
GRADE LOSAL HISAL Section 2).
1 700 1200
2 1201 1400
Consider the query
3 1401 2000 select DEPTNO from EMP;
4 2001 3000 which retrieves the department number for each tuple. Typically, some numbers will appear
5 3001 9999 more than only once in the query result, that is, duplicate result tuples are not automatically
eliminated. Inserting the keyword distinct after the keyword select, however, forces the
elimination of duplicates from the query result.
1.2 Queries (Part I)
It is also possible to specify a sorting order in which the result tuples of a query are displayed.
In order to retrieve the information stored in the database, the SQL query language is used. In For this the order by clause is used and which has one or more attributes listed in the select
the following we restrict our attention to simple SQL queries and defer the discussion of more clause as parameter. desc speci es a descending order and asc speci es an ascending order
complex queries to Section 1.5 (this is also the default order). For example, the query
In SQL a query has the following (simpli ed) form (components in brackets [ ] are optional): select ENAME, DEPTNO, HIREDATE from EMP;
from EMP
order by DEPTNO [asc], HIREDATE desc;
select [distinct] <column(s)> displays the result in an ascending order by the attribute DEPTNO. If two tuples have the same
from <table> attribute value for DEPTNO, the sorting criteria is a descending order by the attribute values of
[ where <condition> ] HIREDATE. For the above query, we would get the following output:
[ order by <column(s) [ascjdesc]> ] ENAME DEPTNO HIREDATE
FORD 10 03-DEC-81
SMITH 20 17-DEC-80
1.2.1 Selecting Columns BLAKE 30 01-MAY-81
WARD 30 22-FEB-81
The columns to be selected from a table are speci ed after the keyword select. This operation ALLEN 30 20-FEB-81
is also called projection. For example, the query ...........................
select LOC, DEPTNO from DEPT;
lists only the number and the location for each tuple from the relation DEPT. If all columns 1.2.2 Selection of Tuples
should be selected, the asterisk symbol \" can be used to denote all attributes. The query
select  from EMP; Up to now we have only focused on selecting (some) attributes of alltuples from a table. If one is
retrieves all tuples with all columns from the table EMP. Instead of an attribute name, the select interested in tuples that satisfy certain conditions, the where clause is used. In a where clause
clause may also contain arithmetic expressions involving arithmetic operators etc. simple conditions based on comparison operators can be combined using the logical connectives
select ENAME, DEPTNO, SAL  1.55 from EMP; and, or, and not to form complex conditions. Conditions may also include pattern matching
operations and even subqueries (Section 1.5).
3 4
Example: List the job title and the salary of those employees whose manager has the 1.2.4 Aggregate Functions
number 7698 or 7566 and who earn more than 1500:
select JOB, SAL Aggregate functions are statistical functions such as count, min, max etc. They are used to
from EMP compute a single value from a set of attribute values of a column:
where (MGR = 7698 or MGR = 7566) and SAL > 1500; count Counting Rows
For all data types, the comparison operators =; != or <>; <; >; <=, => are allowed in the Example: How many tuples are stored in the relation EMP?
conditions of a where clause. select count() from EMP;
Further comparison operators are: Example: How many di erent job titles are stored in the relation EMP?
 Set Conditions: <column> [not] in (<list of values>)
select count(distinct JOB) from EMP;
Example: select  from DEPT where DEPTNO in (20,30);
max Maximum value for a column
min Minimum value for a column
 Null value: <column> is [not] null, Example: List the minimum and maximum salary.
i.e., for a tuple to be selected there must (not) exist a de ned value for this column. select min(SAL), max(SAL) from EMP;
Example: select  from EMP where MGR is not null; Example: Compute the di erence between the minimum and maximum salary.
Note: the operations = null and ! = null are not de ned! select max(SAL) - min(SAL) from EMP;
sum Computes the sum of values (only applicable to the data type number)
 Domain conditions: <column> [not] between <lower bound> and <upper bound> Example: Sum of all salaries of employees working in the department 30.
Example:  select EMPNO, ENAME, SAL from EMP select sum(SAL) from EMP
where SAL between 1500 and 2500; where DEPTNO = 30;
 select ENAME from EMP avg Computes average value for a column (only applicable to the data type number)
where HIREDATE between '02-APR-81' and '08-SEP-81';
Note: avg, min and max ignore tuples that have a null value for the speci ed
attribute, but count considers null values.
1.2.3 String Operations
In order to compare an attribute with a string, it is required to surround the string by apos- 1.3 Data De nition in SQL
trophes, e.g., where LOCATION = 'DALLAS'. A powerful operator for pattern matching is the
like operator. Together with this operator, two special characters are used: the percent sign 1.3.1 Creating Tables
% (also called wild card), and the underline , also called position marker. For example, if
one is interested in all tuples of the table DEPT that contain two C in the name of the depart-
ment, the condition would be where DNAME like '%C%C%'. The percent sign means that any The SQL command for creating an empty table has the following form:
(sub)string is allowed there, even the empty string. In contrast, the underline stands for exactly
one character. Thus the condition where DNAME like '%C C%' would require that exactly one create table <table> (
character appears between the two Cs. To test for inequality, the not clause is used. <column 1> <data type> [not null] [unique] [<column constraint>],
Further string operations are: ::: ::: :::
 upper(<string>) takes a string and converts any letters in it to uppercase, e.g., DNAME <column n> <data type> [not null] [unique] [<column constraint>],
= upper(DNAME) (The name of a department must consist only of upper case letters.) [<table constraint(s)>]
 lower(<string>) converts any letter to lowercase, );
 initcap(<string>) converts the initial letter of every word in <string> to uppercase.
 length(<string>) returns the length of the string. For each column, a name and a data type must be speci ed and the column name must be
 substr(<string>, n [, m]) clips out a m character piece of <string>, starting at position unique within the table de nition. Column de nitions are separated by colons. There is no
n. If m is not speci ed, the end of the string is assumed. di erence between names in lower case letters and names in upper case letters. In fact, the
substr('DATABASE SYSTEMS', 10, 7) returns the string 'SYSTEMS'. only place where upper and lower case letters matter are strings comparisons. A not null
5 6
constraint is directly speci ed after the data type of the column and the constraint requires de nes the attribute EMPNO as the primary key for the table. Each value for the attribute EMPNO
de ned attribute values for that column, di erent from null. thus must appear only once in the table EMP. A table, of course, may only have one primary
key. Note that in contrast to a unique constraint, null values are not allowed.
The keyword unique speci es that no two tuples can have the same attribute value for this
column. Unless the condition not null is also speci ed for this column, the attribute value Example:
null is allowed and two tuples having the attribute value null for this column do not violate We want to create a table called PROJECT to store information about projects. For each
the constraint. project, we want to store the number and the name of the project, the employee number of
the project's manager, the budget and the number of persons working on the project, and
Example: The create table statement for our EMP table has the form the start date and end date of the project. Furthermore, we have the following conditions:
create table EMP ( - a project is identi ed by its project number,
EMPNO number(4) not null,
ENAME varchar2(30) not null, - the name of a project must be unique,
JOB varchar2(10), - the manager and the budget must be de ned.
MGR number(4), Table de nition:
HIREDATE date, create table PROJECT (
SAL number(7,2), PNO number(3) constraint prj pk primary key,
DEPTNO number(2) PNAME varchar2(60) unique,
); PMGR number(4) not null,
Remark: Except for the columns EMPNO and ENAME null values are allowed. PERSONS number(5),
BUDGET number(8,2) not null,
PSTART date,
1.3.2 Constraints PEND date);
The de nition of a table may include the speci cation of integrity constraints. Basically two A unique constraint can include more than one attribute. In this case the pattern unique(<column
types of constraints are provided: column constraints are associated with a single column i>, : : : , <column j>) is used. If it is required, for example, that no two projects have the same
whereas table constraints are typically associated with more than one column. However, any start and end date, we have to add the table constraint
column constraint can also be formulated as a table constraint. In this section we consider only constraint no same dates unique(PEND, PSTART)
very simple constraints. More complex constraints will be discussed in Section 5.1. This constraint has to be de ned in the create table command after both columns PEND and
PSTART have been de ned. A primary key constraint that includes more than only one column
The speci cation of a (simple) constraint has the following form:
can be speci ed in an analogous way.
[constraint <name>] primary key j unique j not null
Instead of a not null constraint it is sometimes useful to specify a default value for an attribute
A constraint can be named. It is advisable to name a constraint in order to get more meaningful if no value is given, e.g., when a tuple is inserted. For this, we use the default clause.
information when this constraint is violated due to, e.g., an insertion of a tuple that violates
the constraint. If no name is speci ed for the constraint, Oracle automatically generates a Example:
name of the pattern SYS C<number>. If no start date is given when inserting a tuple into the table PROJECT, the project start
The two most simple types of constraints have already been discussed: not null and unique. date should be set to January 1st, 1995:
Probably the most important type of integrity constraints in a database are primary key con- PSTART date default('01-JAN-95')
straints. A primary key constraint enables a unique identi cation of each tuple in a table. Note: Unlike integrity constraints, it is not possible to specify a name for a default.
Based on a primary key, the database system ensures that no duplicates appear in a table. For
example, for our EMP table, the speci cation
create table EMP (
EMPNO number(4) constraint pk emp primary key,
: : : );

7 8
1.3.3 Checklist for Creating Tables create table OLDEMP (
ENO number(4) not null,
The following provides a small checklist for the issues that need to be considered before creating HDATE date);
a table. We now can use the table EMP to insert tuples into this new relation:
 What are the attributes of the tuples to be stored? What are the data types of the insert into OLDEMP (ENO, HDATE)
attributes? Should varchar2 be used instead of char ? select EMPNO, HIREDATE from EMP
 Which columns build the primary key? where HIREDATE < '31-DEC-60';
 Which columns do (not) allow null values? Which columns do (not) allow duplicates ?
 Are there default values for certain columns that allow null values ?
1.4.2 Updates
1.4 Data Modi cations in SQL For modifying attribute values of (some) tuples in a table, we use the update statement:
update <table> set
After a table has been created using the create table command, tuples can be inserted into <column i> = <expression i>, : : : , <column j> = <expression j>
the table, or tuples can be deleted or modi ed. [where <condition>];
An expression consists of either a constant (new value), an arithmetic or string operation, or
1.4.1 Insertions an SQL query. Note that the new value to assign to <column i> must a the matching data
type.
The most simple way to insert a tuple into a table is to use the insert statement An update statement without a where clause results in changing respective attributes of all
insert into <table> [(<column i, : : : , column j>)] tuples in the speci ed table. Typically, however, only a (small) portion of the table requires an
values (<value i, : : : , value j>); update.
Examples:
For each of the listed columns, a corresponding (matching) value must be speci ed. Thus an
insertion does not necessarily have to follow the order of the attributes as speci ed in the create  The employee JONES is transfered to the department 20 as a manager and his salary is
table statement. If a column is omitted, the value null is inserted instead. If no column list increased by 1000:
is given, however, for each column as de ned in the create table statement a value must be update EMP set
given. JOB = 'MANAGER', DEPTNO = 20, SAL = SAL +1000
where ENAME = 'JONES';
Examples:  All employees working in the departments 10 and 30 get a 15% salary increase.
insert into PROJECT(PNO, PNAME, PERSONS, BUDGET, PSTART)
values(313, 'DBS', 4, 150000.42, '10-OCT-94'); update EMP set
SAL = SAL  1.15 where DEPTNO in (10,30);
or
Analogous to the insert statement, other tables can be used to retrieve data that are used as
insert into PROJECT new values. In such a case we have a <query> instead of an <expression>.
values(313, 'DBS', 7411, null, 150000.42, '10-OCT-94', null);
Example: All salesmen working in the department 20 get the same salary as the manager
If there are already some data in other tables, these data can be used for insertions into a new who has the lowest salary among all managers.
table. For this, we write a query whose result is a set of tuples to be inserted. Such an insert
statement has the form update EMP set
insert into <table> [(<column i, : : : , column j>)] <query> SAL = (select min(SAL) from EMP
where JOB = 'MANAGER')
Example: Suppose we have de ned the following table: where JOB = 'SALESMAN' and DEPTNO = 20;
Explanation: The query retrieves the minimum salary of all managers. This value then is
assigned to all salesmen working in department 20.
9 10
It is also possible to specify a query that retrieves more than only one value (but still only one select [distinct] [<alias ak >.]<column i>, : : : , [<alias al >.]<column j>
tuple!). In this case the set clause has the form set(<column i, : : : , column j>) = <query>. from <table 1> [<alias a1 >], : : : , <table n> [<alias an>]
It is important that the order of data types and values of the selected row exactly correspond [where <condition>]
to the list of columns in the set clause.
The speci cation of table aliases in the from clause is necessary to refer to columns that have
the same name in di erent tables. For example, the column DEPTNO occurs in both EMP and
1.4.3 Deletions DEPT. If we want to refer to either of these columns in the where or select clause, a table
alias has to be speci ed and put in the front of the column name. Instead of a table alias also
All or selected tuples can be deleted from a table using the delete command: the complete relation name can be put in front of the column such as DEPT.DEPTNO, but this
sometimes can lead to rather lengthy query formulations.
delete from <table> [where <condition>];
If the where clause is omitted, all tuples are deleted from the table. An alternative command 1.5.1 Joining Relations
for deleting all tuples from a table is the truncate table <table> command. However, in this
case, the deletions cannot be undone (see subsequent Section 1.4.4). Comparisons in the where clause are used to combine rows from the tables listed in the from
Example: clause.
Delete all projects (tuples) that have been nished before the actual date (system date): Example: In the table EMP only the numbers of the departments are stored, not their
name. For each salesman, we now want to retrieve the name as well as the
delete from PROJECT where PEND < sysdate; number and the name of the department where he is working:
sysdate is a function in SQL that returns the system date. Another important SQL function select ENAME, E.DEPTNO, DNAME
is user, which returns the name of the user logged into the current Oracle session.
from EMP E, DEPT D
where E.DEPTNO = D.DEPTNO
1.4.4 Commit and Rollback and JOB = 'SALESMAN';
Explanation: E and D are table aliases for EMP and DEPT, respectively. The computation of the
A sequence of database modi cations, i.e., a sequence of insert, update, and delete state- query result occurs in the following manner (without optimization):
ments, is called a transaction. Modi cations of tuples are temporarily stored in the database 1. Each row from the table EMP is combined with each row from the table DEPT (this oper-
system. They become permanent only after the statement commit; has been issued. ation is called Cartesian product ). If EMP contains m rows and DEPT contains n rows, we
As long as the user has not issued the commit statement, it is possible to undo all modi cations thus get n  m rows.
since the last commit. To undo modi cations, one has to issue the statement rollback;. 2. From these rows those that have the same department number are selected (where
E.DEPTNO = D.DEPTNO).
It is advisable to complete each modi cation of the database with a commit (as long as the 3. From this result nally all rows are selected for which the condition JOB = 'SALESMAN'
modi cation has the expected e ect). Note that any data de nition command such as create holds.
table results in an internal commit. A commit is also implicitly executed when the user In this example the joining condition for the two tables is based on the equality operator \=".
terminates an Oracle session. The columns compared by this operator are called join columns and the join operation is called
an equijoin.
1.5 Queries (Part II) Any number of tables can be combined in a select statement.
Example: For each project, retrieve its name, the name of its manager, and the name of
In Section 1.2 we have only focused on queries that refer to exactly one table. Furthermore, the department where the manager is working:
conditions in a where were restricted to simple comparisons. A major feature of relational select ENAME, DNAME, PNAME
databases, however, is to combine (join) tuples stored in di erent tables in order to display from EMP E, DEPT D, PROJECT P
more meaningful and complete information. In SQL the select statement is used for this kind where E.EMPNO = P.MGR
of queries joining relations: and D.DEPTNO = E.DEPTNO;
11 12
It is even possible to join a table with itself: select  from EMP
Example: List the names of all employees together with the name of their manager: where DEPTNO in
(select DEPTNO from DEPT
select E1.ENAME, E2.ENAME where LOC = 'BOSTON');
from EMP E1, EMP E2
where E1.MGR = E2.EMPNO; The subquery retrieves only one value (the number of the department located in Boston). Thus
Explanation: The join columns are MGR for the table E1 and EMPNO for the table E2. it is possible to use \=" instead of in. As long as the result of a subquery is not known in
The equijoin comparison is E1.MGR = E2.EMPNO. advance, i.e., whether it is a single value or a set, it is advisable to use the in operator.
A subquery may use again a subquery in its where clause. Thus conditions can be nested
arbitrarily. An important class of subqueries are those that refer to its surrounding (sub)query
1.5.2 Subqueries and the tables listed in the from clause, respectively. Such type of queries is called correlated
subqueries.
Up to now we have only concentrated on simple comparison conditions in a where clause, i.e.,
we have compared a column with a constant or we have compared two columns. As we have Example: List all those employees who are working in the same department as their manager
already seen for the insert statement, queries can be used for assignments to columns. A query (note that components in [ ] are optional:
result can also be used in a condition of a where clause. In such a case the query is called a
subquery and the complete select statement is called a nested query. select  from EMP E1
where DEPTNO in
A respective condition in the where clause then can have one of the following forms: (select DEPTNO from EMP [E]
1. Set-valued subqueries where [E.]EMPNO = E1.MGR);
<expression> [not] in (<subquery>)
<expression> <comparison operator> [anyjall] (<subquery>) Explanation: The subquery in this example is related to its surrounding query since it refers to
An <expression> can either be a column or a computed value. the column E1.MGR. A tuple is selected from the table EMP (E1) for the query result if the value
2. Test for (non)existence for the column DEPTNO occurs in the set of values select in the subquery. One can think of the
[not] exists (<subquery>) evaluation of this query as follows: For each tuple in the table E1, the subquery is evaluated
individually. If the condition where DEPTNO in : : : evaluates to true, this tuple is selected.
In a where clause conditions using subqueries can be combined arbitrarily by using the logical Note that an alias for the table EMP in the subquery is not necessary since columns without a
connectives and and or. preceding alias listed there always refer to the innermost query and tables.
Example: List the name and salary of employees of the department 20 who are leading Conditions of the form <expression> <comparison operator> [anyjall] <subquery> are used
a project that started before December 31, 1990: to compare a given <expression> with each value selected by <subquery>.
 For the clause any, the condition evaluates to true if there exists at least on row selected
select ENAME, SAL from EMP by the subquery for which the comparison holds. If the subquery yields an empty result
where EMPNO in set, the condition is not satis ed.
(select PMGR from PROJECT  For the clause all, in contrast, the condition evaluates to true if for all rows selected by
where PSTART < '31-DEC-90') the subquery the comparison holds. In this case the condition evaluates to true if the
and DEPTNO =20; subquery does not yield any row or value.
Example: Retrieve all employees who are working in department 10 and who earn at
Explanation: The subquery retrieves the set of those employees who manage a project that least as much as any (i.e., at least one) employee working in department 30:
started before December 31, 1990. If the employee working in department 20 is contained in
this set (in operator), this tuple belongs to the query result set. select  from EMP
where SAL >= any
Example: List all employees who are working in a department located in BOSTON: (select SAL from EMP
where DEPTNO = 30)
and DEPTNO = 10;
13 14
Note: Also in this subquery no aliases are necessary since the columns refer to the innermost Example: Assume that we have a table EMP2 that has the same structure and columns
from clause. as the table EMP:
Example: List all employees who are not working in department 30 and who earn more than  All employee numbers and names from both tables:
select EMPNO, ENAME from EMP
all employees working in department 30:
union
select EMPNO, ENAME from EMP2;
select  from EMP  Employees who are listed in both EMP and EMP2:
where SAL > all select  from EMP
(select SAL from EMP intersect
where DEPTNO = 30) select  from EMP2;
and DEPTNO <> 30;  Employees who are only listed in EMP:
select  from EMP
For all and any, the following equivalences hold: minus
in , = any select  from EMP2;
not in , <> all or != all Each operator requires that both tables have the same data types for the columns to which the
Often a query result depends on whether certain rows do (not) exist in (other) tables. Such operator is applied.
type of queries is formulated using the exists operator.
Example: List all departments that have no employees: 1.5.4 Grouping
select  from DEPT In Section 1.2.4 we have seen how aggregate functions can be used to compute a single value
where not exists for a column. Often applications require grouping rows that have certain properties and then
(select  from EMP applying an aggregate function on one column for each group separately. For this, SQL pro-
where DEPTNO = DEPT.DEPTNO); vides the clause group by <group column(s)>. This clause appears after the where clause
and must refer to columns of tables listed in the from clause.
Explanation: For each tuple from the table DEPT, the condition is checked whether there exists
a tuple in the table EMP that has the same department number (DEPT.DEPTNO). In case no such select <column(s)>
tuple exists, the condition is satis ed for the tuple under consideration and it is selected. If from <table(s)>
there exists a corresponding tuple in the table EMP, the tuple is not selected. where <condition>
group by <group column(s)>
[having <group condition(s)>];
1.5.3 Operations on Result Sets Those rows retrieved by the selected clause that have the same value(s) for <group column(s)>
are grouped. Aggregations speci ed in the select clause are then applied to each group sepa-
Sometimes it is useful to combine query results from two or more queries into a single result. rately. It is important that only those columns that appear in the <group column(s)> clause
SQL supports three set operators which have the pattern: can be listed without an aggregate function in the select clause !
<query 1> <set operator> <query 2>
The set operators are: Example: For each department, we want to retrieve the minimum and maximum salary.
 union [all] returns a table consisting of all rows either appearing in the result of <query select DEPTNO, min(SAL), max(SAL)
1> or in the result of <query 2>. Duplicates are automatically eliminated unless the from EMP
clause all is used. group by DEPTNO;
 intersect returns all rows that appear in both results <query 1> and <query 2>. Rows from the table EMP are grouped such that all rows in a group have the same department
 minus returns those rows that appear in the result of <query 1> but not in the result of number. The aggregate functions are then applied to each such group. We thus get the following
<query 2>. query result:

15 16
DEPTNO MIN(SAL) MAX(SAL) In case that one often refers to tables of other users, it is useful to use a synonym instead of
10 1300 5000 <user>.<table>. In Oracle-SQL a synonym can be created using the command
20 800 3000 create synonym <name> for <user>.<table> ;
30 950 2850 It is then possible to use simply <name> in a from clause. Synonyms can also be created for
Rows to form a group can be restricted in the where clause. For example, if we add the one's own tables.
condition where JOB = 'CLERK', only respective rows build a group. The query then would
retrieve the minimum and maximum salary of all clerks for each department. Note that is not Adding Comments to De nitions
allowed to specify any other column than DEPTNO without an aggregate function in the select For applications that include numerous tables, it is useful to add comments on table de nitions
clause since this is the only column listed in the group by clause (is it also easy to see that or to add comments on columns. A comment on a table can be created using the command
other columns would not make any sense).
comment on table <table> is '<text>';
Once groups have been formed, certain groups can be eliminated based on their properties, A comment on a column can be created using the command
e.g., if a group contains less than three rows. This type of condition is speci ed using the
having clause. As for the select clause also in a having clause only <group column(s)> and comment on column <table>.<column> is '<text>';
aggregations can be used. Comments on tables and columns are stored in the data dictionary. They can be accessed using
the data dictionary views USER TAB COMMENTS and USER COL COMMENTS (see also Section 3).
Example: Retrieve the minimum and maximum salary of clerks for each department having
more than three clerks. Modifying Table- and Column De nitions
select DEPTNO, min(SAL), max(SAL) It is possible to modify the structure of a table (the relation schema) even if rows have already
from EMP been inserted into this table. A column can be added using the alter table command
where JOB = 'CLERK'
group by DEPTNO alter table <table>
having count() > 3; add(<column> <data type> [default <value>] [<column constraint>]);
Note that it is even possible to specify a subquery in a having clause. In the above query, for If more than only one column should be added at one time, respective add clauses need to be
example, instead of the constant 3, a subquery can be speci ed. separated by colons. A table constraint can be added to a table using
alter table <table> add (<table constraint>);
A query containing a group by clause is processed in the following way: Note that a column constraint is a table constraint, too. not null and primary key constraints
1. Select all rows that satisfy the condition speci ed in the where clause. can only be added to a table if none of the speci ed columns contains a null value. Table
2. From these rows form groups according to the group by clause. de nitions can be modi ed in an analogous way. This is useful, e.g., when the size of strings
3. Discard all groups that do not satisfy the condition in the having clause. that can be stored needs to be increased. The syntax of the command for modifying a column
4. Apply aggregate functions to each group. is
5. Retrieve values for the columns and aggregations listed in the select clause. alter table <table>
modify(<column> [<data type>] [default <value>] [<column constraint>]);
Note: In Oracle it is not possible to delete single columns from a table de nition. A
1.5.5 Some Comments on Tables workaround is to create a temporary table and to copy respective columns and rows into this
new table. Furthermore, it is not possible to rename tables or columns.
Accessing tables of other users
Deleting a Table
Provided that a user has the privilege to access tables of other users (see also Section 3), she/he
can refer to these tables in her/his queries. Let <user> be a user in the Oracle system and A table and its rows can be deleted by issuing the command drop table <table> [cascade
<table> a table of this user. This table can be accessed by other (privileged) users using the constraints];.
command
select  from <user>.<table>;
17 18
1.6 Views 2 SQL*Plus
In Oracle the SQL command to create a view (virtual table) has the form
create [or replace] view <view-name> [(<column(s)>)] as
Introduction
<select-statement> [with check option [constraint <name>]]; SQL*Plus is the interactive (low-level) user interface to the Oracle database management
The optional clause or replace re-creates the view if it already exists. <column(s)> names system. Typically, SQL*Plus is used to issue ad-hoc queries and to view the query result on
the columns of the view. If <column(s)> is not speci ed in the view de nition, the columns of the screen. Some of the features of SQL*Plus are:
the view get the same names as the attributes listed in the select statement (if possible).  A built-in command line editor can be used to edit (incorrect) SQL queries. Instead of
this line editor any editor installed on the computer can be invoked.
Example: The following view contains the name, job title and the annual salary of em-  There are numerous commands to format the output of a query.
ployees working in the department 20:  SQL*Plus provides an online-help.
create view DEPT20 as  Query results can be stored in les which then can be printed.
select ENAME, JOB, SAL12 ANNUAL SALARY from EMP
where DEPTNO = 20; Queries that are frequently issued can be saved to a le and invoked later. Queries can be
parameterized such that it is possible to invoke a saved query with a parameter.
In the select statement the column alias ANNUAL SALARY is speci ed for the expression SAL12
and this alias is taken by the view. An alternative formulation of the above view de nition is
create view DEPT20 (ENAME, JOB, ANNUAL SALARY) as A Minimal User Guide
select ENAME, JOB, SAL  12 from EMP
where DEPTNO = 20; Before you start SQL*Plus make sure that the following UNIX shell variables are properly set
A view can be used in the same way as a table, that is, rows can be retrieved from a view (shell variables can be checked using the env command, e.g., env j grep ORACLE):
(also respective rows are not physically stored, but derived on basis of the select statement in  ORACLE HOME, e.g., ORACLE HOME=/usr/pkg/oracle/734
the view de nition), or rows can even be modi ed. A view is evaluated again each time it is  ORACLE SID, e.g, ORACLE SID=prod
accessed. In Oracle SQL no insert, update, or delete modi cations on views are allowed
that use one of the following constructs in the view de nition: In order to invoke SQL*Plus from a UNIX shell, the command sqlplus has to be issued.
SQL*Plus then displays some information about the product, and prompts you for your user
 Joins name and password for the Oracle system.
 Aggregate function such as sum, min, max etc.
 set-valued subqueries (in, any, all) or test for existence (exists)
 group by clause or distinct clause gertz(catbert)54: sqlplus

In combination with the clause with check option any update or insertion of a row into the SQL*Plus: Release 3.3.4.0.1 - Production on Sun Dec 20 19:16:52 1998
view is rejected if the new/modi ed row does not meet the view de nition, i.e., these rows
would not be selected based on the select statement. A with check option can be named Copyright (c) Oracle Corporation 1979, 1996. All rights reserved.
using the constraint clause.
Enter user-name: scott
A view can be deleted using the command delete <view-name>. Enter password:

Connected to:
Oracle7 Server Release 7.3.4.0.1 - Production Release
With the distributed option
PL/SQL Release 2.3.4.0.0 - Production

SQL>

19 20
SQL > is the prompt you get when you are connected to the Oracle database system. In  You can log your SQL*Plus session and thus queries and query results by using the
SQL*Plus you can divide a statement into separate lines, each continuing line is indicated by command spool < le>. All information displayed on screen is then stored in < le>
a prompt such 2>, 3> etc. An SQL statement must always be terminated by a semicolon (;). which automatically gets the extension .lst. The command spool o turns spooling o .
In addition to the SQL statements discussed in the previous section, SQL*Plus provides some  The command copy can be used to copy a complete table. For example, the command
special SQL*Plus commands. These commands need not be terminated by a semicolon. Upper copy from scott/tiger create EMPL using select  from EMP;
and lower case letters are only important for string comparisons. An SQL query can always be copies the table EMP of the user scott with password tiger into the relation EMPL. The
interrupted by using <Control>C. To exit SQL*Plus you can either type exit or quit. relation EMP is automatically created and its structure is derived based on the attributes
listed in the select clause.
 SQL commands saved in a le <name>.sql can be loaded into SQL*Plus and executed
Editor Commands using the command @<name>.
 Comments are introduced by the clause rem[ark] (only allowed between SQL statements),
The most recently issued SQL statement is stored in the SQL bu er, independent of whether the or - - (allowed within SQL statements).
statement has a correct syntax or not. You can edit the bu er using the following commands:
 l[ist] lists all lines in the SQL bu er and sets the current line (marked with an "") to Formatting the Output
the last line in the bu er.
 l<number> sets the actual line to <number>
 c[hange]/<old string>/<new string> replaces the rst occurrence of <old string> by SQL*Plus provides numerous commands to format query results and to build simple reports.
<new string> (for the actual line) For this, format variables are set and these settings are only valid during the SQL*Plus session.
 a[ppend]<string> appends <string> to the current line They get lost after terminating SQL*Plus. It is, however, possible to save settings in a le named
 del deletes the current line login.sql in your home directory. Each time you invoke SQL*Plus this le is automatically
 r[un] executes the current bu er contents loaded.
 get< le> reads the data from the le < le> into the bu er The command column <column name> <option 1> <option 2> : : : is used to format columns
 save< le> writes the current bu er into the le < le> of your query result. The most frequently used options are:
 edit invokes an editor and loads the current bu er into the editor. After exiting the  format A<n> For alphanumeric data, this option sets the length of <column name> to
editor the modi ed SQL statement is stored in the bu er and can be executed (command
r).
<n>. For columns having the data type number, the format command can be used to
specify the format before and after the decimal point. For example, format 99,999.99
The editor can be de ned in the SQL*Plus shell by typing the command de ne editor = speci es that if a value has more than three digits in front of the decimal point, digits are
<name>, where <name> can be any editor such as emacs, vi, joe, or jove. separated by a colon, and only two digits are displayed after the decimal point.
 The option heading <text> relabels <column name> and gives it a new heading.
 null <text> is used to specify the output of null values (typically, null values are not
SQL*Plus Help System and Other Useful Commands displayed).
 column <column name> clear deletes the format de nitions for <column name>.
 To get the online help in SQL*Plus just type help <command>, or just help to get
information about how to use the help command. In Oracle Version 7 one can get the The command set linesize <number> can be used to set the maximum length of a single
complete list of possible commands by typing help command. line that can be displayed on screen. set pagesize <number> sets the total number of lines
 To change the password, in Oracle Version 7 the command SQL*Plus displays before printing the column names and headings, respectively, of the selected
alter user <user> identi ed by <new password>; rows.
is used. In Oracle Version 8 the command passw <user> prompts the user for the
old/new password. Several other formatting features can be enabled by setting SQL*Plus variables. The command
 The command desc[ribe] <table> lists all columns of the given table together with their show all displays all variables and their current values. To set a variable, type set <variable>
data types and information about whether null values are allowed or not. <value>. For example, set timing on causes SQL*Plus to display timing statistics for each
 You can invoke a UNIX command from the SQL*Plus shell by using host <UNIX command>. SQL command that is executed. set pause on [<text>] makes SQL*Plus wait for you to press
For example, host ls -la *.sql lists all SQL les in the current directory. Return after the number of lines de ned by set pagesize has been displayed. <text> is the
message SQL*Plus will display at the bottom of the screen as it waits for you to hit Return.

21 22
3 Oracle Data Dictionary returns all information about the columns of one's own tables.
Each SQL query requires various internal accesses to the tables and views of the data dictionary.
The Oracle data dictionary is one of the most important components of the Oracle DBMS. Since the data dictionary itself consists of tables, Oracle has to generate numerous SQL
It contains all information about the structures and objects of the database such as tables, statements to check whether the SQL command issued by a user is correct and can be executed.
columns, users, data les etc. The data stored in the data dictionary are also often called
metadata. Although it is usually the domain of database administrators (DBAs), the data Example: The SQL query
dictionary is a valuable source of information for end users and developers. The data dictionary select  from EMP
consists of two levels: the internal level contains all base tables that are used by the various where SAL > 2000;
DBMS software components and they are normally not accessible by end users. The external requires a veri cation whether (1) the table EMP exists, (2) the user has the privilege to access
level provides numerous views on these base tables to access information about objects and this table, (3) the column SAL is de ned for this table etc.
structures at di erent levels of detail.

3.1 Data Dictionary Tables 3.2 Data Dictionary Views


The external level of the data dictionary provides users a front end to access information
An installation of an Oracle database always includes the creation of three standard Oracle relevant to the users. This level provides numerous views (in Oracle7 approximately 540)
users: that represent (a portion of the) data from the base tables in a readable and understandable
 SYS: This is the owner of all data dictionary tables and views. This user has the highest manner. These views can be used in SQL queries just like normal tables.
privileges to manage objects and structures of an Oracle database such as creating new
users. The views provided by the data dictionary are divided into three groups: USER, ALL, and DBA.
 SYSTEM: is the owner of tables used by di erent tools such SQL*Forms, SQL*Reports etc. The group name builds the pre x for each view name. For some views, there are associated
This user has less privileges than SYS. synonyms as given in brackets below.
 PUBLIC: This is a \dummy" user in an Oracle database. All privileges assigned to this
user are automatically assigned to all users known in the database.  USER : Tuples in the USER views contain information about objects owned by the account
The tables and views provided by the data dictionary contain information about performing the SQL query (current user)
 users and their privileges, USER TABLES all tables with their name, number of columns, storage
 tables, table columns and their data types, integrity constraints, indexes, information, statistical information etc. (TABS)
 statistics about tables and indexes used by the optimizer, USER CATALOG tables, views, and synonyms (CAT)
 privileges granted on database objects, USER COL COMMENTS comments on columns
 storage structures of the database. USER CONSTRAINTS constraint de nitions for tables
USER INDEXES all information about indexes created for tables (IND)
The SQL command USER OBJECTS all database objects owned by the user (OBJ)
select  from DICT[IONARY]; USER TAB COLUMNS columns of the tables and views owned by the user
(COLS)
lists all tables and views of the data dictionary that are accessible to the user. The selected USER TAB COMMENTS comments on tables and views
information includes the name and a short description of each table and view. Before issuing USER TRIGGERS triggers de ned by the user
this query, check the column de nitions of DICT[IONARY] using desc DICT[IONARY] and set USER USERS information about the current user
the appropriate values for column using the format command. USER VIEWS views de ned by the user
The query  ALL : Rows in the ALL views include rows of the USER views and all information about
select  from TAB; objects that are accessible to the current user. The structure of these views is analogous
retrieves the names of all tables owned by the user who issues this command. The query to the structure of the USER views.
select  from COL;
23 24
ALL CATALOG owner, name and type of all accessible tables, views, and 4 Application Programming
synonyms
ALL TABLES owner and name of all accessible tables
ALL OBJECTS owner, type, and name of accessible database objects 4.1 PL/SQL
ALL TRIGGERS : : :
ALL USERS ::: 4.1.1 Introduction
ALL VIEWS :::
 DBA : The DBA views encompass information about all database objects, regardless of the The development of database applications typically requires language constructs similar to those
owner. Only users with DBA privileges can access these views. that can be found in programming languages such as C, C++, or Pascal. These constructs are
necessary in order to implement complex data structures and algorithms. A major restriction
DBA TABLES tables of all users in the database of the database language SQL, however, is that many tasks cannot be accomplished by using
DBA CATALOG tables, views, and synonyms de ned in the database only the provided language elements.
DBA OBJECTS object of all users
DBA DATA FILES information about data les PL/SQL (Procedural Language/SQL) is a procedural extension of Oracle-SQL that o ers lan-
DBA USERS information about all users known in the database guage constructs similar to those in imperative programming languages. PL/SQL allows users
and designers to develop complex database applications that require the usage of control struc-
tures and procedural elements such as procedures, functions, and modules.
The basic construct in PL/SQL is a block. Blocks allow designers to combine logically related
(SQL-) statements into units. In a block, constants and variables can be declared, and variables
can be used to store query results. Statements in a PL/SQL block include SQL statements,
control structures (loops), condition statements (if-then-else), exception handling, and calls of
other PL/SQL blocks.
PL/SQL blocks that specify procedures and functions can be grouped into packages. A package
is similar to a module and has an interface and an implementation part. Oracle o ers several
prede ned packages, for example, input/output routines, le handling, job scheduling etc. (see
directory $ORACLE HOME/rdbms/admin).
Another important feature of PL/SQL is that it o ers a mechanism to process query results
in a tuple-oriented way, that is, one tuple at a time. For this, cursors are used. A cursor
basically is a pointer to a query result and is used to read attribute values of selected tuples
into variables. A cursor typically is used in combination with a loop construct such that each
tuple read by the cursor can be processed individually.
In summary, the major goals of PL/SQL are to
 increase the expressiveness of SQL,
 process query results in a tuple-oriented way,
 optimize combined SQL statements,
 develop modular database application programs,
 reuse program code, and
 reduce the cost for maintaining and changing applications.

25 26
4.1.2 Structure of PL/SQL-Blocks Instead of specifying a data type, one can also refer to the data type of a table column (so-called
anchored declaration). For example, EMP.Empno%TYPE refers to the data type of the column
Empno in the relation EMP. Instead of a single variable, a record can be declared that can store a
PL/SQL is a block-structured language. Each block builds a (named) program unit, and
blocks can be nested. Blocks that build a procedure, a function, or a package must be named. complete tuple from a given table (or query result). For example, the data type DEPT%ROWTYPE
A PL/SQL block has an optional declare section, a part containing PL/SQL statements, and an speci es a record suitable to store all attribute values of a complete row from the table DEPT.
optional exception-handling part. Thus the structure of a PL/SQL looks as follows (brackets Such records are typically used in combination with a cursor. A eld in a record can be accessed
[ ] enclose optional parts): using <record name>.<column name>, for example, DEPT.Deptno.
[<Block header>] A cursor declaration speci es a set of tuples (as a query result) such that the tuples can be
[declare processed in a tuple-oriented way (i.e., one tuple at a time) using the fetch statement. A cursor
<Constants> declaration has the form
<Variables> cursor <cursor name> [(<list of parameters>)] is <select statement>;
<Cursors> The cursor name is an undeclared identi er, not the name of any PL/SQL variable. A parameter
<User de ned exceptions>] has the form <parameter name> <parameter type>. Possible parameter types are char,
begin varchar2, number, date and boolean as well as corresponding subtypes such as integer.
<PL/SQL statements> Parameters are used to assign values to the variables that are given in the select statement.
[exception
<Exception handling>] Example: We want to retrieve the following attribute values from the table EMP in a tuple-
end; oriented way: the job title and name of those employees who have been hired
The block header speci es whether the PL/SQL block is a procedure, a function, or a package. after a given date, and who have a manager working in a given department.
If no header is speci ed, the block is said to be an anonymous PL/SQL block. Each PL/SQL cursor employee cur (start date date, dno number) is
block again builds a PL/SQL statement. Thus blocks can be nested like blocks in conventional select JOB, ENAME from EMP E where HIREDATE > start date
programming languages. The scope of declared variables (i.e., the part of the program in which and exists (select  from EMP
one can refer to the variable) is analogous to the scope of variables in programming languages where E.MGR = EMPNO and DEPTNO = dno);
such as C or Pascal.
If (some) tuples selected by the cursor will be modi ed in the PL/SQL block, the clause for
4.1.3 Declarations update[(<column(s)>)] has to be added at the end of the cursor declaration. In this case
Constants, variables, cursors, and exceptions used in a PL/SQL block must be declared in the selected tuples are locked and cannot be accessed by other users until a commit has been
declare section of that block. Variables and constants can be declared as follows: issued. Before a declared cursor can be used in PL/SQL statements, the cursor must be
opened, and after processing the selected tuples the cursor must be closed. We discuss the
<variable name> [constant] <data type> [not null] [:= <expression>]; usage of cursors in more detail below.
Valid data types are SQL data types (see Section 1.1) and the data type boolean. Boolean Exceptions are used to process errors and warnings that occur during the execution of PL/SQL
data may only be true, false, or null. The not null clause requires that the declared variable statements in a controlled manner. Some exceptions are internally de ned, such as ZERO DIVIDE.
must always have a value di erent from null. <expression> is used to initialize a variable. Other exceptions can be speci ed by the user at the end of a PL/SQL block. User de ned ex-
If no expression is speci ed, the value null is assigned to the variable. The clause constant ceptions need to be declared using <name of exception> exception. We will discuss exception
states that once a value has been assigned to the variable, the value cannot be changed (thus handling in more detail in Section 4.1.5
the variable becomes a constant). Example:
declare 4.1.4 Language Elements
hire date date; /* implicit initialization with null */
job title varchar2(80) := 'Salesman'; In addition to the declaration of variables, constants, and cursors, PL/SQL o ers various lan-
emp found boolean; /* implicit initialization with null */ guage constructs such as variable assignments, control structures (loops, if-then-else), procedure
salary incr constant number(3,2) := 1.5; /* constant */ and function calls, etc. However, PL/SQL does not allow commands of the SQL data de nition
::: language such as the create table statement. For this, PL/SQL provides special packages.
begin : : : end;
27 28
Furthermore, PL/SQL uses a modi ed select statement that requires each selected tuple to be A loop can be named. Naming a loop is useful whenever loops are nested and inner loops are
assigned to a record (or a list of variables). completed unconditionally using the exit <label name>; statement.
There are several alternatives in PL/SQL to a assign a value to a variable. The most simple Whereas the number of iterations through a while loop is unknown until the loop completes,
way to assign a value to a variable is the number of iterations through the for loop can be speci ed using two integers.
declare [<< <label name> >>]
counter integer := 0; for <index> in [reverse] <lower bound>..<upper bound> loop
::: <sequence of statements>
begin end loop [<label name>] ;
counter := counter + 1; The loop counter <index> is declared implicitly. The scope of the loop counter is only the
Values to assign to a variable can also be retrieved from the database using a select statement for loop. It overrides the scope of any variable having the same name outside the loop. Inside
select <column(s)> into <matching list of variables> the for loop, <index> can be referenced like a constant. <index> may appear in expressions,
from <table(s)> where <condition>; but one cannot assign a value to <index>. Using the keyword reverse causes the iteration to
proceed downwards from the higher bound to the lower bound.
It is important to ensure that the select statement retrieves at most one tuple ! Otherwise Processing Cursors: Before a cursor can be used, it must be opened using the open statement
it is not possible to assign the attribute values to the speci ed list of variables and a run-
time error occurs. If the select statement retrieves more than one tuple, a cursor must be used open <cursor name> [(<list of parameters>)] ;
instead. Furthermore, the data types of the speci ed variables must match those of the retrieved The associated select statement then is processed and the cursor references the rst selected
attribute values. For most data types, PL/SQL performs an automatic type conversion (e.g., tuple. Selected tuples then can be processed one tuple at a time using the fetch command
from integer to real). fetch <cursor name> into <list of variables>;
Instead of a list of single variables, a record can be given after the keyword into. Also in this The fetch command assigns the selected attribute values of the current tuple to the list of
case, the select statement must retrieve at most one tuple ! variables. After the fetch command, the cursor advances to the next tuple in the result set.
Note that the variables in the list must have the same data types as the selected values. After
declare all tuples have been processed, the close command is used to disable the cursor.
employee rec EMP%ROWTYPE ;
max sal EMP.SAL%TYPE ; close <cursor name>;
begin
select EMPNO, ENAME, JOB, MGR, SAL, COMM, HIREDATE, DEPTNO The example below illustrates how a cursor is used together with a continuous loop:
into employee rec
from EMP where EMPNO = 5698; declare
select max(SAL) into max sal from EMP; cursor emp cur is select  from EMP;
::: emp rec EMP%ROWTYPE ;
end; emp sal EMP.SAL%TYPE ;
begin
PL/SQL provides while-loops, two types of for-loops, and continuous loops. Latter ones open emp cur;
are used in combination with cursors. All types of loops are used to execute a sequence of loop
statements multiple times. The speci cation of loops occurs in the same way as known from fetch emp cur into emp rec;
imperative programming languages such as C or Pascal. exit when emp cur%NOTFOUND;
emp sal := emp rec.sal;
A while-loop has the pattern <sequence of statements>
[<< <label name> >>] end loop;
while <condition> loop close emp cur;
<sequence of statements>; :::
end loop [<label name>] ; end;
29 30
Each loop can be completed unconditionally using the exit clause: Starting with the rst condition, if a condition yields true, its corresponding sequence of state-
exit [<block label>] [when <condition>] ments is executed, otherwise control is passed to the next condition. Thus the behavior of this
type of PL/SQL statement is analogous to if-then-else statements in imperative programming
Using exit without a block label causes the completion of the loop that contains the exit state- languages.
ment. A condition can be a simple comparison of values. In most cases, however, the condition
refers to a cursor. In the example above, %NOTFOUND is a predicate that evaluates to false if the Except data de nition language commands such as create table, all types of SQL statements
most recent fetch command has read a tuple. The value of <cursor name>%NOTFOUND is null can be used in PL/SQL blocks, in particular delete, insert, update, and commit. Note
before the rst tuple is fetched. The predicate evaluates to true if the most recent fetch failed that in PL/SQL only select statements of the type select <column(s)> into are allowed, i.e.,
to return a tuple, and false otherwise. %FOUND is the logical opposite of %NOTFOUND. selected attribute values can only be assigned to variables (unless the select statement is used
in a subquery). The usage of select statements as in SQL leads to a syntax error. If update or
Cursor for loops can be used to simplify the usage of a cursor: delete statements are used in combination with a cursor, these commands can be restricted to
[<< <label name> >>] currently fetched tuple. In these cases the clause where current of <cursor name> is added
for <record name> in <cursor name>[(<list of parameters>)] loop as shown in the following example.
<sequence of statements> Example: The following PL/SQL block performs the following modi cations: All employees
end loop [<label name>]; having 'KING' as their manager get a 5% salary increase.
A record suitable to store a tuple fetched by the cursor is implicitly declared. Furthermore,
this loop implicitly performs a fetch at each iteration as well as an open before the loop is declare
entered and a close after the loop is left. If at an iteration no tuple has been fetched, the loop manager EMP.MGR%TYPE ;
is automatically terminated without an exit. cursor emp cur mgr no
( number) is
select SAL from EMP
It is even possible to specify a query instead of <cursor name> in a for loop: where MGR = mgr no
for <record name> in (<select statement>) loop for update of SAL;
<sequence of statements> begin
end loop; select EMPNO into manager from EMP
That is, a cursor needs not be speci ed before the loop is entered, but is de ned in the select where ENAME = 'KING';
statement. for emp rec in emp cur(manager) loop
update EMP set SAL = emp rec.sal  1.05
Example: where current of emp cur;
for sal rec in (select SAL + COMM total from EMP) loop end loop;
::: ; commit;
end loop; end;
total is an alias for the expression computed in the select statement. Thus, at each iteration Remark: Note that the record emp rec is implicitly de ned. We will discuss another version of
only one tuple is fetched. The record sal rec, which is implicitly de ned, then contains only this block using parameters in Section 4.1.6.
one entry which can be accessed using sal rec.total. Aliases, of course, are not necessary if
only attributes are selected, that is, if the select statement contains no arithmetic operators
or aggregate functions. 4.1.5 Exception Handling
For conditional control, PL/SQL o ers if-then-else constructs of the pattern A PL/SQL block may contain statements that specify exception handling routines. Each error
if <condition> then <sequence of statements> or warning during the execution of a PL/SQL block raises an exception. One can distinguish
[elsif ] <condition> then <sequence of statements> between two types of exceptions:
:::  system de ned exceptions
[else] <sequence of statements> end if ;  user de ned exceptions (which must be declared by the user in the declaration part of a
block where the exception is used/implemented)

31 32
System de ned exceptions are always automatically raised whenever corresponding errors or If a PL/SQL program is executed from the SQL*Plus shell, exception handling routines may
warnings occur. User de ned exceptions, in contrast, must be raised explicitly in a sequence contain statements that display error or warning messages on the screen. For this, the procedure
of statements using raise <exception name>. After the keyword exception at the end of a raise application error can be used. This procedure has two parameters <error number>
block, user de ned exception handling routines are implemented. An implementation has the and <message text>. <error number> is a negative integer de ned by the user and must range
pattern between -20000 and -20999. <error message> is a string with a length up to 2048 characters.
The concatenation operator \jj" can be used to concatenate single strings to one string. In order
when <exception name> then <sequence of statements>; to display numeric variables, these variables must be converted to strings using the function
The most common errors that can occur during the execution of PL/SQL programs are handled to char. If the procedure raise application error is called from a PL/SQL block, processing
by system de ned exceptions. The table below lists some of these exceptions with their names the PL/SQL block terminates and all database modi cations are undone, that is, an implicit
and a short description. rollback is performed in addition to displaying the error message.
Exception name Number Remark Example:
CURSOR ALREADY OPEN ORA-06511 You have tried to open a cursor which is if emp sal  1.05 > 4000
already open then raise application error(-20010, 'Salary increase for employee with Id '
INVALID CURSOR ORA-01001 Invalid cursor operation such as fetching jj to char(Emp no) jj ' is too high');
from a closed cursor
NO DATA FOUND ORA-01403 A select : : : into or fetch statement re- 4.1.6 Procedures and Functions
turned no tuple
TOO MANY ROWS ORA-01422 A select : : : into statement returned more PL/SQL provides sophisticated language constructs to program procedures and functions as
than one tuple stand-alone PL/SQL blocks. They can be called from other PL/SQL blocks, other procedures
ZERO DIVIDE ORA-01476 You have tried to divide a number by 0 and functions. The syntax for a procedure de nition is
create [or replace] procedure <procedure name> [(<list of parameters>)] is
Example: <declarations>
declare begin
emp sal EMP.SAL%TYPE ; <sequence of statements>
emp no EMP.EMPNO%TYPE ; [exception
too high sal exception; <exception handling routines>]
begin end [<procedure name>];
select EMPNO, SAL into emp no, emp sal A function can be speci ed in an analogous way
from EMP where ENAME = 'KING'; create [or replace] function <function name> [(<list of parameters>)]
if emp sal  1.05 > 4000 then raise too high sal return <data type> is
else update EMP set SQL : : : :::
end if ;
exception The optional clause or replace re-creates the procedure/function. A procedure can be deleted
when NO DATA FOUND { { no tuple selected using the command drop procedure <procedure name> (drop function <function name>).
then rollback; In contrast to anonymous PL/SQL blocks, the clause declare may not be used in proce-
when too high sal then insert into high sal emps values(emp no); dure/function de nitions.
commit;
end; Valid parameters include all data types. However, for char, varchar2, and number no length
and scale, respectively, can be speci ed. For example, the parameter number(6) results in a
compile error and must be replaced by number. Instead of explicit data types, implicit types
After the keyword when a list of exception names connected with or can be speci ed. The last of the form %TYPE and %ROWTYPE can be used even if constrained declarations are referenced.
when clause in the exception part may contain the exception name others. This introduces A parameter is speci ed as follows:
the default exception handling routine, for example, a rollback.
<parameter name> [IN j OUT j IN OUT] <data type> [f := j DEFAULTg <expression>]
33 34
The optional clauses IN, OUT, and IN OUT specify the way in which the parameter is used. all sal := all sal + emp sal.sal ;
The default mode for a parameter is IN. IN means that the parameter can be referenced inside end loop;
the procedure body, but it cannot be changed. OUT means that a value can be assigned to return all sal;
the parameter in the body, but the parameter's value cannot be referenced. IN OUT allows end get dept salary;
both assigning values to the parameter and referencing the parameter. Typically, it is sucient
to use the default mode for parameters. In order to call a function from the SQL*Plus shell, it is necessary to rst de ne a vari-
Example: The subsequent procedure is used to increase the salary of all employees who work able to which the return value can be assigned. In SQL*Plus a variable can be de ned us-
in the department given by the procedure's parameter. The percentage of the salary increase ing the command variable <variable name> <data type>;, for example, variable salary
is given by a parameter, too. number. The above function then can be called using the command execute :salary :=
get dept salary(20); Note that the colon \:" must be put in front of the variable.
create procedure raise salary(dno number, percentage number DEFAULT 0.5) is Further information about procedures and functions can be obtained using the help command
cursor emp cur (dept no number) is in the SQL*Plus shell, for example, help [create] function, help subprograms, help stored
select SAL from EMP where DEPTNO = dept no subprograms.
for update of SAL;
empsal number(8);
begin 4.1.7 Packages
open emp cur(dno); - - Here dno is assigned to dept no
loop It is essential for a good programming style that logically related blocks, procedures, and func-
fetch emp cur into empsal; tions are combined into modules, and each module provides an interface which allows users
exit when emp cur%NOTFOUND; and designers to utilize the implemented functionality. PL/SQL supports the concept of mod-
update EMP set SAL = empsal  ((100 + percentage)/100) ularization by which modules and other constructs can be organized into packages. A package
where current of emp cur; consists of a package speci cation and a package body. The package speci cation de nes the
end loop; interface that is visible for application programmers, and the package body implements the
close emp cur; package speci cation (similar to header- and source les in the programming language C).
commit;
end raise salary; Below a package is given that is used to combine all functions and procedures to manage
information about employees.
This procedure can be called from the SQL*Plus shell using the command
execute raise salary(10, 3); create package manage_employee as -- package specification
If the procedure is called only with the parameter 10, the default value 0.5 is assumed as function hire_emp (name varchar2, job varchar2, mgr number, hiredate date,
speci ed in the list of parameters in the procedure de nition. If a procedure is called from a sal number, comm number default 0, deptno number)
PL/SQL block, the keyword execute is omitted. return number;
procedure fire_emp (emp_id number);
Functions have the same structure as procedures. The only di erence is that a function returns procedure raise_sal (emp_id number, sal_incr number);
a value whose data type (unconstrained) must be speci ed. end manage_employee;

Example: create package body manage_employee as


function hire_emp (name varchar2, job varchar2, mgr number, hiredate date,
create function get dept salary(dno number) return number is sal number, comm number default 0, deptno number)
all sal number;
return number is
begin -- Insert a new employee with a new employee Id
all sal := 0; new_empno number(10);
foremp sal in (select SAL from EMP where DEPTNO = dno
begin
and SAL is not null) loop select emp_sequence.nextval into new_empno from dual;

35 36
insert into emp values(new_empno, name, job, mgr, hiredate, Procedure name Remark
sal, comm, deptno); DBMS OUTPUT.ENABLE enables output
return new_empno; DBMS OUTPUT.DISABLE disables output
end hire_emp; DBMS OUTPUT.PUT (<string>) appends (displays) <string> to output
bu er
procedure fire_emp(emp_id number) is DBMS OUTPUT.PUT LINE(<string>) appends <string> to output bu er and
-- deletes an employee from the table EMP appends a new-line marker
begin DBMS OUTPUT.NEW LINE displays a new-line marker
delete from emp where empno = emp_id;
if SQL%NOTFOUND then -- delete statement referred to invalid emp_id Before strings can be displayed on the screen, the output has to be enabled either using the
raise_application_error(-20011, 'Employee with Id ' || procedure DBMS OUTPUT.ENABLE or using the SQL*Plus command set serveroutput on (before
to_char(emp_id) || ' does not exist.'); the procedure that produces the output is called).
end if;
end fire_emp;
Further packages provided by Oracle are UTL FILE for reading and writing les from PL/SQL
programs, DBMS JOB for job scheduling, and DBMS SQL to generate SQL statements dynamically,
that is, during program execution. The package DBMS SQL is typically used to create and
procedure raise_sal(emp_id number, sal_incr number) is
delete tables from within PL/SQL programs. More packages can be found in the directory
-- modify the salary of a given employee
$ORACLE HOME/rdbms/admin.
begin
update emp set sal = sal + sal_incr
where empno = emp_id; 4.1.8 Programming in PL/SQL
if SQL%NOTFOUND then
raise_application_error(-20012, 'Employee with Id ' ||
to_char(emp_id) || ' does not exist');
Typically one uses an editor such as emacs or vi to write a PL/SQL program. Once a program
end if;
has been stored in a le <name> with the extension .sql, it can be loaded into SQL*Plus
end raise_sal;
using the command @<name>. It is important that the last line of the le contains a slash
end manage_employee;
\/".
If the procedure, function, or package has been successfully compiled, SQL*Plus displays the
Remark: In order to compile and execute the above package, it is necessary to create rst the message PL/SQL procedure successfully completed. If the program contains errors, these
required sequence (help sequence): are displayed in the format ORA-n <message text>, where n is a number and <message text> is
a short description of the error, for example, ORA-1001 INVALID CURSOR. The SQL*Plus com-
create sequence emp sequence start with 8000 increment by 10; mand show errors [<functionjprocedurejpackagejpackage bodyjtrigger> <name>] displays all
A procedure or function implemented in a package can be called from other procedures and compilation errors of the most recently created or altered function (or procedure, or package
functions using the statement <package name>.<procedure name>[(<list of parameters>)]. etc.) in more detail. If this command does not show any errors, try select  from USER ERRORS.
Calling such a procedure from the SQL*Plus shell requires a leading execute. Under the UNIX shell one can also use the command oerr ORA n to get information of the
Oracle o ers several prede ned packages and procedures that can be used by database users following form:
and application developers. A set of very useful procedures is implemented in the package error description
DBMS OUTPUT. This package allows users to display information to their SQL*Plus session's Cause: Reason for the error
screen as a PL/SQL program is executed. It is also a very useful means to debug PL/SQL Action: Suggested action
programs that have been successfully compiled, but do not behave as expected. Below some of
the most important procedures of this package are listed:

37 38
4.2 Embedded SQL and Pro*C Editor Program Development

The query language constructs of SQL described in the previous sections are suited for formulat- Host Program including SQL and PL/SQL commands
ing ad-hoc queries, data manipulation statements and simple PL/SQL blocks in simple, inter- Program (<program>.pc)
active tools such as SQL*Plus. Many data management tasks, however, occur in sophisticated
engineering applications and these tasks are too complex to be handled by such an interactive Precompiler Translates SQL and PL/SQL commands into function calls
tool. Typically, data are generated and manipulated in computationally complex application
programs that are written in a Third-Generation-Language (3GL), and which, therefore, need
an interface to the database system. Furthermore, a majority of existing data-intensive en- Source ‘pure’ C-Program including libraries (.h)
Program (<program>.c)
gineering applications are written previously using an imperative programming language and
now want to make use of the functionality of a database system, thus requiring an easy to use
programming interface to the database system. Such an interface is provided in the form of C-Compiler cc, gcc or g++
Embedded SQL, an embedding of SQL into various programming languages, such as C, C++,
Cobol, Fortran etc. Embedded SQL provides application programmers a suitable means to Object- executable
combine the computing power of a programming language with the database manipulation and Program Linker Program
management capabilities of the declarative query language SQL.
Oracle Run-Time Library C Standard-Libraries
Since all these interfaces exhibit comparable functionalities, in the following we describe the
embedding of SQL in the programming language C. For this, we base our discussion on the Figure 1: Translation of a Pro*C Program
Oracle interface to C, called Pro*C. The emphasis in this section is placed on the description
of the interface, not on introducing the programming language C.
char <Name> single character
char <Name>[n] array of n characters
4.2.1 General Concepts int integer
Programs written in Pro*C and which include SQL and/or PL/SQL statements are precom- oat oating point
piled into regular C programs using a precompiler that typically comes with the database VARCHAR<Name>[n] variable length strings
management software (precompiler package). In order to make SQL and PL/SQL statements VARCHAR2 is converted by the Pro*C precompiler into a structure with an n-byte character
in a Proc*C program (having the sux .pc) recognizable by the precompiler, they are always array and a 2-bytes length eld. The declaration of host variables occurs in a declare section
preceded by the keywords EXEC SQL and end with a semicolon \;". The Pro*C precompiler having the following pattern:
replaces such statements with appropriate calls to functions implemented in the SQL runtime EXEC SQL BEGIN DECLARE SECTION
library. The resulting C program then can be compiled and linked using a normal C compiler
like any other C program. The linker includes the appropriate Oracle speci c libraries. Fig- <Declaration of host variables>
ure 1 summarizes the steps from the source code containing SQL statements to an executable /* e.g., VARCHAR userid[20]; */
program. /* e.g., char test ok; */
EXEC SQL END DECLARE SECTION
4.2.2 Host and Communication Variables In a Pro*C program at most one such a declare section is allowed. The declaration of cursors
and exceptions occurs outside of such a declare section for host variables. In a Pro*C program
As it is the case for PL/SQL blocks, also the rst part of a Pro*C program has a declare section. host variables referenced in SQL and PL/SQL statements must be pre xed with a colon \:".
In a Pro*C program, in a declare section so-called host variables are speci ed. Host variables Note that it is not possible to use C function calls and most of the pointer expressions as host
are the key to the communication between the host program and the database. Declarations variable references.
of host variables can be placed wherever normal C variable declarations can be placed. Host 2 Note: all uppercase letters; varchar2 is not allowed!
variables are declared according to the C syntax. Host variables can be of the following data
types:

39 40
4.2.3 The Communication Area sqlerrd Array of binary integers, has 6 elements:
sqlerrd[0],sqlerrd[1],sqlerrd[3],sqlerrd[6] not used; sqlerrd[2] =
In addition to host language variables that are needed to pass data between the database and number of rows processed by the most recent SQL statement; sqlerrd[4] =
C program (and vice versa), one needs to provide some status variables containing program o set specifying position of most recent parse error of SQL statement.
runtime information. The variables are used to pass status information concerning the database sqlwarn Array with eight elements used as warning (not error!) ags. Flag is set by
access to the application program so that certain events can be handled in the program properly. assigning it the character `W'.
The structure containing the status variables is called SQL Communication Area or SQLCA, sqlwarn[0]: only set if other ag is set
for short, and has to be included after the declare section using the statement sqlwarn[1]: if truncated column value was assigned to a host variable
EXEC SQL INCLUDE SQLCA.H sqlwarn[2]: null column is not used in computing an aggregate function
sqlwarn[3]: number of columns in select is not equal to number of host
In the variables de ned in this structure, information about error messages as well as program variables speci ed in into
status information is maintained: sqlwarn[4]: if every tuple was processed by an update or delete statement
without a where clause
struct sqlca sqlwarn[5]: procedure/function body compilation failed because of
{ a PL/SQL error
/* ub1 */ char sqlcaid[8]; sqlwarn[6] and sqlwarn[7]: not used
/* b4 */ long sqlabc; sqlext not used
/* b4 */ long sqlcode;
struct Components of this structure can be accessed and veri ed during runtime, and appropriate
{ handling routines (e.g., exception handling) can be executed to ensure a correct behavior of the
/* ub2 */ unsigned short sqlerrml; application program. If at the end of the program the variable sqlcode contains a 0, then the
/* ub1 */ char sqlerrmc[70]; execution of the program has been successful, otherwise an error occurred.
} sqlerrm;
/* ub1 */ char sqlerrp[8];
/* b4 */ long sqlerrd[6];
4.2.4 Exception Handling
/* ub1 */ char sqlwarn[8];
/* ub1 */ char sqlext[8];
There are two ways to check the status of your program after executable SQL statements which
};
may result in an error or warning: (1) either by explicitly checking respective components
of the SQLCA structure, or (2) by doing automatic error checking and handling using the
WHENEVER statement. The complete syntax of this statement is
The elds in this structure have the following meaning: EXEC SQL WHENEVER <condition> <action>;
sqlcaid Used to identify the SQLCA, set to \SQLCA"
sqlabc Holds the length of the SQLCA structure By using this command, the program then automatically checks the SQLCA for <condition>
sqlcode Holds the status code of the most recently executed SQL (PL/SQL) statement
and executes the given <action>. <condition> can be one of the following:
0 =^ No error, statement successfully completed
> 0 =^ Statement executed and exception detected. Typical situations are where  SQLERROR: sqlcode has a negative value, that is, an error occurred
fetch or select into returns no rows.  SQLWARNING: In this case sqlwarn[0] is set due to a warning
< 0 =^ Statement was not executed because of an error; transaction should
be rolled back explicitly.  NOT FOUND: sqlcode has a positive value, meaning that no row was found that satis es
sqlerrm Structure with two components the where condition, or a select into or fetch statement returned no rows
sqlerrml: length of the message text in sqlerrmc, and
sqlerrmc: error message text (up to 70 characters) corresponding to the error <action> can be
code recorded in sqlcode
sqlerrp Not used  STOP: the program exits with an exit() call, and all SQL statements that have not
been committed so far are rolled back
41 42
 CONTINUE: if possible, the program tries to continue with the statement following the #include <stdlib.h>
error resulting statement
/* Declare section for host variables */
 DO <function>: the program transfers processing to an error handling function named EXEC SQL BEGIN DECLARE SECTION;
<function> VARCHAR userid[20];
VARCHAR passwd[20];
 GOTO <label>: program execution branches to a labeled statement (see example) int empno;
VARCHAR ename[15];
4.2.5 Connecting to the Database float sal;
float min_sal;
At the beginning of Pro*C program, more precisely, the execution of embedded SQL or PL/SQL EXEC SQL END DECLARE SECTION;
statements, one has to connect to the database using a valid Oracle account and password.
Connecting to the database occurs trough the embedded SQL statement /* Load SQL Communication Area */
EXEC SQL INCLUDE SQLCA.H;
EXEC SQL CONNECT :<Account> IDENTIFIED BY :<Password>.
Both <Account> and <Password> are host variables of the type VARCHAR and must main() /* Main program */
be speci ed and handled respectively (see also the sample Pro*C program in Section 4.2.7). { int retval;
<Account> and <Password> can be speci ed in the Pro*C program, but can also be entered /* Catch errors automatically and go to error handling rountine */
at program runtime using, e.g., the C function scanf. EXEC SQL WHENEVER SQLERROR GOTO error;

/* Connect to Oracle as SCOTT/TIGER; both are host variables */


4.2.6 Commit and Rollback /* of type VARCHAR; Account and Password are specified explicitly */
strcpy(userid.arr,"SCOTT"); /* userid.arr := "SCOTT" */
Before a program is terminated by the c exit function and if no error occurred, database userid.len=strlen(userid.arr); /* uid.len := 5 */
modi cations through embedded insert, update, and delete statements must be committed. strcpy(passwd.arr,"SCOTT"); /* passwd.arr := "TIGER" */
This is done by using the embedded SQL statement passwd.len=strlen(passwd.arr); /* passwd.len := 5 */
EXEC SQL COMMIT WORK RELEASE;
If a program error occurred and previous non-committed database modi cations need to be EXEC SQL CONNECT :userid IDENTIFIED BY :passwd;
undone, the embedded SQL statement
printf("Connected to ORACLE as: %s\n\n", userid.arr);
EXEC SQL ROLLBACK WORK RELEASE;
has to be speci ed in the respective error handling routine of the Pro*C program. /* Enter minimum salary by user */
printf("Please enter minimum salary > ");
retval = scanf("%f", &min_sal);
4.2.7 Sample Pro*C Program
if(retval != 1) {
The following Pro*C program connects to the database using the database account scott/tiger. printf("Input error!!\n");
The database contains information about employees and departments (see the previous exam- EXEC SQL ROLLBACK WORK RELEASE;
ples used in this tutorial). The user has to enter a salary which then is used to retrieve all /* Disconnect from ORACLE */
employees (from the relation EMP) who earn more than the given minimum salary. Retrieving exit(2); /* Exit program */
and processing individual result tuples occurs through using a PL/SQL cursor in a C while-loop. }

/* Declarations */ /* Declare cursor; cannot occur in declare section! */


#include <stdio.h> EXEC SQL DECLARE EMP_CUR CURSOR FOR
#include <string.h> SELECT EMPNO,ENAME,SAL FROM EMP

43 44
WHERE SAL>=:min_sal; 5 Integrity Constraints and Triggers
/* Print Table header, run cursor through result set */
printf("Empployee-ID Employee-Name Salary \n"); 5.1 Integrity Constraints
printf("--------------- ----------------- -------\n");
EXEC SQL OPEN EMP_CUR; In Section 1 we have discussed three types of integrity constraints: not null constraints, primary
EXEC SQL FETCH EMP_CUR INTO :empno, :ename, :sal; /* Fetch 1.tuple */ keys, and unique constraints. In this section we introduce two more types of constraints that
while(sqlca.sqlcode==0) { /* are there more tuples ? */ can be speci ed within the create table statement: check constraints (to restrict possible
ename.arr[ename.len] = '\0'; /* "End of String" */ attribute values), and foreign key constraints (to specify interdependencies between relations).
printf("%15d %-17s %7.2f\n",empno,ename.arr,sal);
EXEC SQL FETCH EMP_CUR INTO :empno, :ename, :sal; /* get next tuple */
} 5.1.1 Check Constraints
EXEC SQL CLOSE EMP_CUR;
Often columns in a table must have values that are within a certain range or that satisfy certain
/* Disconnect from database and terminate program */
conditions. Check constraints allow users to restrict possible attribute values for a column to
EXEC SQL COMMIT WORK RELEASE;
admissible ones. They can be speci ed as column constraints or table constraints. The syntax
printf("\nDisconnected from ORACLE\n");
for a check constraint is
exit(0);
[constraint <name>] check(<condition>)
/* Error Handling: Print error message */ If a check constraint is speci ed as a column constraint, the condition can only refer that
error: printf("\nError: %.70s \n",sqlca.sqlerrm.sqlerrmc); column.
EXEC SQL ROLLBACK WORK RELEASE;
exit(1);
Example: The name of an employee must consist of upper case letters only; the minimum
}
salary of an employee is 500; department numbers must range between 10 and
100:
create table EMP
( ::: ,
ENAME varchar2(30) constraint check name
check(ENAME = upper(ENAME) ),
SAL number(5,2) constraint check sal check(SAL >= 500),
DEPTNO number(3) constraint check deptno
check(DEPTNO between 10 and 100) );
If a check constraint is speci ed as a table constraint, <condition> can refer to all columns
of the table. Note that only simple conditions are allowed. For example, it is not allowed
to refer to columns of other tables or to formulate queries as check conditions. Furthermore,
the functions sysdate and user cannot be used in a condition. In principle, thus only simple
attribute comparisons and logical connectives such as and, or, and not are allowed. A check
condition, however, can include a not null constraint:
SAL number(5,2) constraint check sal check(SAL is not null and SAL >= 500),
Without the not null condition, the value null for the attribute SAL would not cause a violation
of the constraint.
Example: At least two persons must participate in a project, and the project's start date
must be before the project's end date:

45 46
create table PROJECT includes only one column, the clause foreign key is not used. It is very important that a
( ::: , foreign key must refer to the complete primary key of a parent-table, not only a subset of the
PERSONS number(5) constraint check pers check (PERSONS > 2), attributes that build the primary key !
::: ,
constraint dates ok check(PEND > PSTART) ); EMP (Child-Table) DEPT (Parent-Table)

. . . DEPTNO DEPTNO . . .
In this table de nition, check pers is a column constraint and dates ok is a table constraint. . . . 10 10 . . .
The database system automatically checks the speci ed conditions each time a database mod- . . . 10 20 . . .
i cation is performed on this relation. For example, the insertion . . . 20 30 . . .
. . . 20 40 . . .
insert into EMP values(7999,'SCOTT','CLERK',7698,'31-OCT-94',450,10); . . . 30 references
causes a constraint violation primary key
foreign key
ORA-02290: check constraint (CHECK SAL) violated
and the insertion is rejected. Figure 2: Foreign Key Constraint between the Tables EMP and DEPT

5.1.2 Foreign Key Constraints In order to satisfy a foreign key constraint, each row in the child-table has to satisfy one of the
following two conditions:
A foreign key constraint (or referential integrity constraint) can be speci ed as a column con-  the attribute value (list of attribute values) of the foreign key must appear as a primary
straint or as a table constraint: key value in the parent-table, or
 the attribute value of the foreign key is null (in case of a composite foreign key, at least
[constraint <name>] [foreign key (<column(s)>)] one attribute value of the foreign key is null )
references <table>[(<column(s)>)]
[on delete cascade] According to the above de nition for the table EMP, an employee must not necessarily work in
a department, i.e., for the attribute DEPTNO the value null is admissible.
This constraint speci es a column or a list of columns as a foreign key of the referencing table.
The referencing table is called the child-table, and the referenced table is called the parent-table. Example: Each project manager must be an employee:
In other words, one cannot de ne a referential integrity constraint that refers to a table R before create table PROJECT
that table R has been created. ( PNO number(3) constraint prj pk primary key,
PMGR number(4) not null
The clause foreign key has to be used in addition to the clause references if the foreign constraint fk pmgr references EMP,
key includes more than one column. In this case, the constraint has to be speci ed as a table : : : );
constraint. The clause references de nes which columns of the parent-table are referenced. If
only the name of the parent-table is given, the list of attributes that build the primary key of Because only the name of the parent-table is given (DEPT), the primary key of this relation
that table is assumed. is assumed. A foreign key constraint may also refer to the same table, i.e., parent-table and
Example: Each employee in the table EMP must work in a department that is contained child-table are identical.
in the table DEPT: Example: Each manager must be an employee:
create table EMP create table EMP
( EMPNO number(4) constraint pk emp primary key, ( EMPNO number(4) constraint emp pk primary key,
::: , :::
DEPTNO number(3) constraint fk deptno references DEPT(DEPTNO) ); MGR number(4) not null
The column DEPTNO of the table EMP (child-table) builds the foreign key and references the constraint fk mgr references EMP,
primary key of the table DEPT (parent-table). The relationship between these two tables is :::
illustrated in Figure 2. Since in the table de nition above the referential integrity constraint );

47 48
5.1.3 More about Column- and Table Constraints Tuples contained in the query result now can be modi ed (e.g., by increasing the salary of
managers) such that adding the constraint can be performed successfully. Note that it is
If a constraint is de ned within the create table command or added using the alter table important to delete \old" violations from the relation EXCEPTIONS before it is used again.
command (compare Section 1.5.5), the constraint is automatically enabled. A constraint can If a table is used as a reference of a foreign key, this table can only be dropped using the
be disabled using the command command drop table <table> cascade constraints;. All other database objects that refer
alter table <table> disable to this table (e.g., triggers, see Section 5.2) remain in the database system, but they are not
constraint <name> j primary key j unique[<column(s)>] valid.
[cascade]; Information about integrity constraints, their status (enabled, disabled) etc. is stored in the
To disable a primary key, one must disable all foreign key constraints that depend on this data dictionary, more precisely, in the tables USER CONSTRAINTS and USER CONS CONSTRAINTS.
primary key. The clause cascade automatically disables foreign key constraints that depend
on the (disabled) primary key.
Example: Disable the primary key of the table DEPT and disable the foreign key constraint 5.2 Triggers
in the table EMP:
alter table DEPT disable primary key cascade; 5.2.1 Overview
In order to enable an integrity constraint, the clause enable is used instead of disable. A The di erent types of integrity constraints discussed so far provide a declarative mechanism
constraint can only be enabled successfully if no tuple in the table violates the constraint. Oth- to associate \simple" conditions with a table such as a primary key, foreign keys or domain
erwise an error message is displayed. Note that for enabling/disabling an integrity constraint constraints. Complex integrity constraints that refer to several tables and attributes (as they
it is important that you have named the constraints. are known as assertions in the SQL standard) cannot be speci ed within table de nitions. Trig-
gers, in contrast, provide a procedural technique to specify and maintain integrity constraints.
In order to identify those tuples that violate an integrity constraint whose activation failed, one Triggers even allow users to specify more complex integrity constraints since a trigger essen-
can use the clause exceptions into EXCEPTIONS with the alter table statement. EXCEPTIONS tially is a PL/SQL procedure. Such a procedure is associated with a table and is automatically
is a table that stores information about violating tuples.3 Each tuple in this table is identi ed called by the database system whenever a certain modi cation (event ) occurs on that table.
by the attribute ROWID. Every tuple in a database has a pseudo-column ROWID that is used to Modi cations on a table may include insert, update, and delete operations (Oracle 7).
identify tuples. Besides the rowid, the name of the table, the table owner as well as the name
of the violated constraint are stored.
Example: Assume we want to add an integrity constraint to our table EMP which requires 5.2.2 Structure of Triggers
that each manager must earn more than 4000:
alter table EMP add constraint manager sal A trigger de nition consists of the following (optional) components:
check(JOB != 'MANAGER' or SAL >= 4000)  trigger name
exceptions into EXCEPTIONS; create [or replace] trigger <trigger name>
 trigger time point
If the table EMP already contains tuples that violate the constraint, the constraint cannot before j after
be activated and information about violating tuples is automatically inserted into the table  triggering event(s)
EXCEPTIONS. insert or update [of <column(s)>] or delete on <table>
Detailed information about the violating tuples can be obtained by joining the tables EMP and  trigger type (optional)
EXCEPTIONS, based on the join attribute ROWID:
for each row
 trigger restriction (only for for each row triggers !)
select EMP., CONSTRAINT from EMP, EXCEPTIONS when (<condition>)
where EMP.ROWID = EXCEPTIONS.ROW ID;  trigger body
3 Before this table can be used, it must be created using the SQL script utlexcept.sql which can be found <PL/SQL block>
in the directory $ORACLE HOME/rdbms/admin.
The clause replace re-creates a previous trigger de nition having the same <trigger name>.
The name of a trigger can be chosen arbitrarily, but it is a good programming style to use
49 50
a trigger name that re ects the table and the event(s), e.g., upd ins EMP. A trigger can be these triggers more eciently. Statement level triggers are in general only used in combination
invoked before or after the triggering event. The triggering event speci es before (after) with the trigger time point after.
which operations on the table <table> the trigger is executed. A single event is an insert, an In a trigger de nition the when clause can only be used in combination with a for each row
update, or a delete; events can be combined using the logical connective or. If for an update trigger. The clause is used to further restrict when the trigger is executed. For the speci cation
trigger no columns are speci ed, the trigger is executed after (before) <table> is updated. If of the condition in the when clause, the same restrictions as for the check clause hold. The
the trigger should only be executed when certain columns are updated, these columns must be only exceptions are that the functions sysdate and user can be used, and that it is possible to
speci ed after the event update. If a trigger is used to maintain an integrity constraint, the refer to the old/new attribute values of the actual row. In the latter case, the colon \:" must
triggering events typically correspond to the operations that can violate the integrity constraint. not be used, i.e., only old.<attribute> and new.<attribute>.
In order to program triggers eciently (and correctly) it is essential to understand the di erence The trigger body consists of a PL/SQL block. All SQL and PL/SQL commands except the
between a row level trigger and a statement level trigger. A row level trigger is de ned using two statements commit and rollback can be used in a trigger's PL/SQL block. Furthermore,
the clause for each row. If this clause is not given, the trigger is assumed to be a statement additional if constructs allow to execute certain parts of the PL/SQL block depending on the
trigger. A row trigger executes once for each row after (before) the event. In contrast, a triggering event. For this, the three constructs if inserting, if updating[('<column>')], and
statement trigger is executed once after (before) the event, independent of how many rows are if deleting exist. They can be used as shown in the following example:
a ected by the event. For example, a row trigger with the event speci cation after update is
executed once for each row a ected by the update. Thus, if the update a ects 20 tuples, the create or replace trigger emp check
trigger is executed 20 times, for each row at a time. In contrast, a statement trigger is only
executed once. after insert or delete or update on EMP
for each row
When combining the di erent types of triggers, there are twelve possible trigger con gurations begin
that can be de ned for a table: if inserting then
<PL/SQL block>
event trigger time point trigger type end if ;
before after statement row if updating then
insert X X X X <PL/SQL block>
update X X X X end if ;
delete X X X X if deleting then
Figure 3: Trigger Types <PL/SQL block>
end if ;
end;
Row triggers have some special features that are not provided by statement triggers:
It is important to understand that the execution of a trigger's PL/SQL block builds a part of
Only with a row trigger it is possible to access the attribute values of a tuple before and after the transaction that contains the triggering event. Thus, for example, an insert statement in
the modi cation (because the trigger is executed once for each tuple). For an update trigger, a PL/SQL block can cause another trigger to be executed. Multiple triggers and modi cations
the old attribute value can be accessed using :old.<column> and the new attribute value thus can lead to a cascading execution of triggers. Such a sequence of triggers terminates
can be accessed using :new.<column>. For an insert trigger, only :new.<column> can be successfully if (1) no exception is raised within a PL/SQL block, and (2) no declaratively
used, and for a delete trigger only :old.<column> can be used (because there exists no old, speci ed integrity constraint is violated. If a trigger raises an exception in a PL/SQL block,
respectively, new value of the tuple). In these cases, :new.<column> refers to the attribute all modi cations up to the beginning of the transaction are rolled back. In the PL/SQL block
value of <column> of the inserted tuple, and :old.<column> refers to the attribute value of of a trigger, an exception can be raised using the statement raise application error (see
<column> of the deleted tuple. In a row trigger thus it is possible to specify comparisons Section 4.1.5). This statement causes an implicit rollback. In combination with a row trigger,
between old and new attribute values in the PL/SQL block, e.g., \if :old.SAL < :new.SAL raise application error can refer to old/new values of modi ed rows:
then : : : ". If for a row trigger the trigger time point before is speci ed, it is even possible to raise application error(,20020, 'Salary increase from ' jj to char(:old.SAL) jj ' to '
modify the new values of the row, e.g., :new.SAL := :new.SAL  1.05 or :new.SAL := :old.SAL. to char(:new.SAL) jj ' is too high'); or
Such modi cations are not possible with after row triggers. In general, it is advisable to use a
after row trigger if the new row is not modi ed in the PL/SQL block. Oracle then can process raise application error(,20030, 'Employee Id ' jj
to char(:new .EMPNO) jj ' does not exist.');
51 52
5.2.3 Example Triggers trig2.sql

Suppose we have to maintain the following integrity constraint: \The salary of an employee create or replace trigger check salary SALGRADE
di erent from the president cannot be decreased and must also not be increased more than before update or delete on SALGRADE
10%. Furthermore, depending on the job title, each salary must lie within a certain salary for each row
range. when (new.MINSAL > old.MINSAL
We assume a table SALGRADE that stores the minimum (MINSAL) and maximum (MAXSAL) salary
or new.MAXSAL < old.MAXSAL)
{ { only restricting a salary range can cause a constraint violation
for each job title (JOB). Since the above condition can be checked for each employee individually, declare
we de ne the following row trigger: job emps number(3) := 0;
trig1.sql begin
if deleting then { { Does there still exist an employee having the deleted job ?
create or replace trigger check salary EMP select count() into job emps from EMP
after insert or update of SAL, JOB on EMP where JOB = :old.JOB;
for each row if job emps != 0 then
when (new.JOB != 'PRESIDENT') { { trigger restriction raise application error(-20240, ' There still exist employees with the job ' jj
declare :old.JOB);
minsal, maxsal SALGRADE.MAXSAL%TYPE ; end if ;
begin end if ;
{ { retrieve minimum and maximum salary for JOB if updating then
select MINSAL, MAXSAL into minsal, maxsal from SALGRADE { { Are there employees whose salary does not lie within the modi ed salary range ?
where JOB = :new.JOB; select count() into job emps from EMP
{ { If the new salary has been decreased or does not lie within the salary range, where JOB = :new.JOB
{ { raise an exception and SAL not between :new.MINSAL and :new.MAXSAL;
if (:new.SAL < minsal or :new.SAL > maxsal) then if job emps != 0 then { { restore old salary ranges
raise application error(-20225, 'Salary range exceeded'); :new.MINSAL := :old.MINSAL;
elsif (:new.SAL < :old.SAL) then :new.MAXSAL := :old.MAXSAL;
raise application error(-20230, 'Salary has been decreased'); end if ;
elsif (:new.SAL > 1.1  :old.SAL) then end if ;
raise application error(-20235, 'More than 10% salary increase'); end;
end if ;
end; In this case a before trigger must be used to restore the old attribute values of an updated
row.
We use an after trigger because the inserted or updated row is not changed within the PL/SQL Suppose we furthermore have a column BUDGET in our table DEPT that is used to store the
block (e.g., in case of a constraint violation, it would be possible to restore the old attribute budget available for each department. Assume the integrity constraint requires that the total
values). of all salaries in a department must not exceed the department's budget. Critical operations
Note that also modi cations on the table SALGRADE can cause a constraint violation. In order on the relation EMP are insertions into EMP and updates on the attributes SAL or DEPTNO.
to maintain the complete condition we de ne the following trigger on the table SALGRADE. In
case of a violation by an update modi cation, however, we do not raise an exception, but
restore the old attribute values.

53 54
trig3.sql declare
sal sum number;
create or replace trigger check budget EMP begin
after insert or update of SAL, DEPTNO on EMP select sum(SAL) into sal sum from EMP;
declare ::: ;
cursor DEPT CUR is end;
select DEPTNO, BUDGET from DEPT;
DNO DEPT.DEPTNO%TYPE ; For example, if an update statement of the form update EMP set SAL = SAL  1.1 is executed
ALLSAL DEPT.BUDGET%TYPE ; on the table EMP, the above trigger is executed once for each modi ed row. While the table is
DEPT SAL number; being modi ed by the update command, it is not possible to access all tuples of the table using
begin the select command, because it is locked. In this case we get the error message
open DEPT CUR;
loop ORA-04091: table EMP is mutating, trigger may not read or modify it
fetch DEPT CUR into DNO, ALLSAL; ORA-06512: at line 4
exit when DEPT CUR%NOTFOUND; ORA-04088: error during execution of trigger 'CHECK_SAL_EMP'
select sum(SAL) into DEPT SAL from EMP
where DEPTNO = DNO;
if DEPT SAL > ALLSAL then The only way to access the table, or more precisely, to access the modi ed tuple, is to use
raise application error(-20325, 'Total of salaries in the department ' jj :old.<column> and :new.<column>.
to char(DNO) jj ' exceeds budget'); It is recommended to follow the rules below for the de nition of integrity maintaining triggers:
end if ;
end loop;
close DEPT CUR; identify operations and tables that are critical for the integrity constraint
end; for each such table check
if constraint can be checked at row level then
In this case we use a statement trigger on the relation EMP because we have to apply an aggregate if checked rows are modi ed in trigger then
function on the salary of all employees that work in a particular department. For the relation use before row trigger
DEPT, we also have to de ne a trigger which, however, can be formulated as a row trigger.
else use after row trigger
else
use after statement trigger
5.2.4 Programming Triggers
For programmers, row triggers are the most critical type of triggers because they include several Triggers are not exclusively used for integrity maintenance. They can also be used for
restrictions. In order to ensure read consistency, Oracle performs an exclusive lock on the
table at the beginning of an insert, update, or delete statement. That is, other users cannot  Monitoring purposes, such as the monitoring of user accesses and modi cations on certain
access this table until modi cations have been successfully completed. In this case, the table sensitive tables.
currently modi ed is said to be a mutating table. The only way to access a mutating table in  Logging actions, e.g., on tables:
a trigger is to use :old.<column> and :new.<column> in connection with a row trigger.
Example of an erroneous row trigger: create trigger LOG EMP
after insert or update or delete on EMP
create trigger check sal EMP begin
after update of SAL on EMP if inserting then
for each row insert into EMP LOG values(user, 'INSERT', sysdate);
55 56
end if ; 6 System Architecture
if updating then
insert into EMP LOG values(user, 'UPDATE', sysdate); In the following sections we discuss the main components of the Oracle DBMS (Version 7.X)
end if ; architecture (Section 6.1) and the logical and physical database structures (Sections 6.2 and
if deleting then 6.3). We furthermore sketch how SQL statements are processed (Section 6.4) and how database
insert into EMP LOG values(user, 'DELETE', sysdate); objects are created (Section 6.5).
end if ;
end; 6.1 Storage Management and Processes
By using a row trigger, even the attribute values of the modi ed tuples can be stored in The Oracle DBMS server is based on a so-called Multi-Server Architecture. The server is
the table EMP LOG. responsible for processing all database activities such as the execution of SQL statements, user
and resource management, and storage management. Although there is only one copy of the
 automatic propagation of modi cations. For example, if a manager is transfered to an- program code for the DBMS server, to each user connected to the server logically a separate
other department, a trigger can be de ned that automatically transfers the manager's server is assigned. The following gure illustrates the architecture of the Oracle DBMS
employees to the new department. consisting of storage structures, processes, and les.

5.2.5 More about Triggers User 1 User 2 User 3 User n

If a trigger is speci ed within the SQL*Plus shell, the de nition must end with a point \." in
the last line. Issuing the command run causes SQL*Plus to compile this trigger de nition. A
trigger de nition can be loaded from a le using the command @. Note that the last line in Server- Server- Server- Server-

the le must consist of a slash \/". Process Process Process Process

PGA PGA PGA PGA


A trigger de nition cannot be changed, it can only be re-created using the or replace clause.
The command drop <trigger name> deletes a trigger. System Global Area (SGA)
After a trigger de nition has been successfully compiled, the trigger automatically is enabled.
The command alter trigger <trigger name> disable is used to deactivate a trigger. All Redo-Log- Shared Pool

triggers de ned on a table can be (de)activated using the command


Buffer
Dictionary Cache

alter table <Tabelle> enable j disable all trigger;


Database
Buffer

The data dictionary stores information about triggers in the table USER TRIGGERS. The infor- Log Library Cache

mation includes the trigger name, type, table, and the code for the PL/SQL block. Archive
Buffer

Background Processes

DBWR LGWR ARCH PMON SMON

Datafiles Redo-Log Files Control Files Archive- and Backup Files

Figure 4: Oracle System Architecture

57 58
Each time a database is started on the server (instance startup ), a portion of the computer's of processes varies depending on the instance con guration. One can distinguish between user
main memory is allocated, the so-called System Global Area (SGA). The SGA consists of the processes and Oracle processes. Oracle processes are typically background processes that
shared pool, the database bu er, and the redo-log bu er. Furthermore, several background perform I/O operations at database run-time.
processes are started. The combination of SGA and processes is called database instance. The
memory and processes associated with an instance are responsible for eciently managing the DBWR This process is responsible for managing the contents of the database bu er and the
data stored in the database, and to allow users accessing the database concurrently. The dictionary cache. For this, DBWR writes modi ed data blocks to the data les. The
Oracle server can manage multiple instances, typically each instance is associated with a process only writes blocks to the les if more blocks are going to be read into the bu er
particular application domain. than free blocks exist.
The SGA serves as that part of the memory where all database operations occur. If several LGWR This process manages writing the contents of the redo-log-bu er to the redo-log les.
users connect to an instance at the same time, they all share the SGA. The information stored SMON When a database instance is started, the system monitor process performs instance
in the SGA can be subdivided into the following three caches. recovery as needed (e.g., after a system crash). It cleans up the database from aborted
transactions and objects involved. In particular, this process is responsible for coalescing
Database Bu er The database bu er is a cache in the SGA used to hold the data blocks that contiguous free extents to larger extents (space defragmentation, see Section 6.2).
are read from data les. Blocks can contain table data, index data etc. Data blocks are PMON The process monitor process cleans up behind failed user processes and it also cleans
modi ed in the database bu er. Oracle manages the space available in the database up the resources used by these processes. Like SMON, PMON wakes up periodically to
bu er by using a least recently used (LRU) algorithm. When free space is needed in the check whether it is needed.
bu er, the least recently used blocks will be written out to the data les. The size of the
database bu er has a major impact on the overall performance of a database. ARCH (optional) The LGWR background process writes to the redo-log les in a cyclic
Redo-Log-Bu er This bu er contains information about changes of data blocks in the database fashion. Once the last redo-log le is lled, LGWR overwrites the contents of the rst
bu er. While the redo-log-bu er is lled during data modi cations, the log writer process redo-log le. It is possible to run a database instance in the archive-log mode. In this case
writes information about the modi cations to the redo-log les. These les are used after, the ARCH process copies redo-log entries to archive les before the entries are overwritten
e.g., a system crash, in order to restore the database (database recovery). by LGWR. Thus it is possible to restore the contents of the database to any time after
the archive-log mode was started.
Shared Pool The shared pool is the part of the SGA that is used by all users. The main USER The task of this process is to communicate with other processes started by application
components of this pool are the dictionary cache and the library cache. Information about programs such as SQL*Plus. The USER process then is responsible for sending respective
database objects is stored in the data dictionary tables. When information is needed by operations and requests to the SGA or PGA. This includes, for example, reading data
the database, for example, to check whether a table column speci ed in a query exists, blocks.
the dictionary tables are read and the data returned is stored in the dictionary cache.
Note that all SQL statements require accessing the data dictionary. Thus keeping relevant
portions of the dictionary in the cache may increase the performance. The library cache 6.2 Logical Database Structures
contains information about the most recently issued SQL commands such as the parse
tree and query execution plan. If the same SQL statement is issued several times, it need For the architecture of an Oracle database we distinguish between logical and physical
not be parsed again and all information about executing the statement can be retrieved database structures that make up a database. Logical structures describe logical areas of stor-
from the library cache. age (name spaces) where objects such as tables can be stored. Physical structures, in contrast,
are determined by the operating system les that constitute the database.
Further storage structures in the computer's main memory are the log-archive bu er (optional) The logical database structures include:
and the Program Global Area (PGA). The log-archive bu er is used to temporarily cache redo-
log entries that are to be archived in special les. The PGA is the area in the memory that is Database A database consists of one or more storage divisions, so-called tablespaces.
used by a single Oracle user process. It contains the user's context area (cursors, variables
etc.), as well as process information. The memory in the PGA is not sharable. Tablespaces A tablespace is a logical division of a database. All database objects are logically
stored in tablespaces. Each database has at least one tablespace, the SYSTEM tablespace,
For each database instance, there is a set of processes. These processes maintain and enforce the that contains the data dictionary. Other tablespaces can be created and used for di erent
relationships between the database's physical structures and memory structures. The number applications or tasks.
59 60
Segments If a database object (e.g., a table or a cluster) is created, automatically a portion As mentioned in Section 6.1, aside from data les three further types of les are associated with
of the tablespace is allocated. This portion is called a segment. For each table there a database instance:
is a table segment. For indexes so-called index segments are allocated. The segment
associated with a database object belongs to exactly one tablespace. Redo-Log Files Each database instance maintains a set of redo-log les. These les are used
Extent An extent is the smallest logical storage unit that can be allocated for a database to record logs of all transactions. The logs are used to recover the database's transactions
object, and it consists a contiguous sequence of data blocks! If the size of a database in their proper order in the event of a database crash (the recovering operations are called
object increases (e.g., due to insertions of tuples into a table), an additional extent is roll forward). When a transaction is executed, modi cations are entered in the redo-log
allocated for the object. Information about the extents allocated for database objects bu er, while the blocks a ected by the transactions are not immediately written back to
can be found in the data dictionary view USER EXTENTS. disk, thus allowing optimizing the performance through batch writes.
Control Files Each database instance has at least one control le. In this le the name of
A special type of segments are rollback segments. They don't contain a database object, but the database instance and the locations (disks) of the data les and redo-log les are
contain a \before image" of modi ed data for which the modifying transaction has not yet recorded. Each time an instance is started, the data and redo-log les are determined by
been committed. Modi cations are undone using rollback segments. Oracle uses rollback using the control le(s).
segments in order to maintain read consistency among multiple users. Furthermore, rollback
segments are used to restore the \before image" of modi ed tuples in the event of a rollback of Archive/Backup Files If an instance is running in the archive-log mode, the ARCH process
the modifying transaction. archives the modi cations of the redo-log les in extra archive or backup les. In contrast
to redo-log les, these les are typically not overwritten.
Typically, an extra tablespace (RBS) is used to store rollback segments. This tablespace can be
de ned during the creation of a database. The size of this tablespace and its segments depends The following ER schema illustrates the architecture of an Oracle database instance and the
on the type and size of transactions that are typically performed by application programs. relationships between physical and logical database structures (relationships can be read as
A database typically consists of a SYSTEM tablespace containing the data dictionary and \consists of").
further internal tables, procedures etc., and a tablespace for rollback segments. Additional ta-
blespaces include a tablespace for user data (USERS), a tablespace for temporary query results redo-log file database control file
and tables (TEMP), and a tablespace used by applications such as SQL*Forms (TOOLS).

6.3 Physical Database Structure


The physical database structure of an Oracle database is determined by les and data blocks:
datafile tablespace table
Data Files A tablespace consists of one or more operating system les that are stored on disk. index
Thus a database essentially is a collection of data les that can be stored on di erent segment
storage devices (magnetic tape, optical disks etc.). Typically, only magnetic disks are cluster
used. Multiple data les for a tablespace allows the server to distribute a database object
rollback seg.
over multiple disks (depending on the size of the object). block extent

Blocks An extent consists of one or more contiguous Oracle data blocks. A block determines
the nest level of granularity of where data can be stored. One data block corresponds Figure 5: Relationships between logical and physical database structures
to a speci c number of bytes of physical database space on disk. A data block size is
speci ed for each Oracle database when the database is created. A database uses and
allocates free database space in Oracle data blocks. Information about data blocks can
be retrieved from the data dictionary views USER SEGMENTS and USER EXTENTS. These
views show how many blocks are allocated for a database object and how many blocks
are available (free) in a segment/extent.
61 62
6.4 Steps in Processing an SQL Statement database object will be, some default storage parameters are used. The user, however, has
the possibility to explicitly specify the storage parameters using a storage clause in, e.g., the
In the following we sketch how an SQL statement is processed by the Oracle server and which create table statement. This speci cation then overwrites the system parameters and allows
processes and bu ers involved. the user to specify the (expected) storage size of the object in terms of extents.
Suppose the following table de nition that includes a storage clause:
1. Assume a user (working with SQL*Plus) issues an update statement on the table TAB such
that more than one tuple is a ected by the update. The statement is passed to the server
by the USER process. Then the server (or rather the query processor) checks whether create table STOCKS
this statement is already contained in the library cache such that the corresponding (ITEM varchar2(30),
QUANTITY number(4))
information (parse tree, execution plan) can be used. If the statement can not be found,
it is parsed and after verifying the statement (user privileges, a ected tables and columns) storage (initial 1M next 400k
using data from the dictionary cache, a query execution plan is generated by the query minextents 1 maxextents 20 pctincrease 50);
optimizer. Together with the parse tree, this plan is stored in the library cache.
2. For the objects a ected by the statement (here the table TAB) it is checked, whether the
initial and next specify the size of the rst and next extents, respectively. In the de nition
above, the initial extent has a size of 1MB, and the next extent has a size of 400KB. The
corresponding data blocks already exist in the database bu er. If not, the USER process parameter minextents speci es the total number of extents allocated when the segment is
reads the data blocks into the database bu er. If there is not enough space in the bu er, created. This parameter allows the user to allocate a large amount of space when an object
the least recently used blocks of other objects are written back to the disk by the DBWR is created, even if the space available is not contiguous. The default and minimum value
process. is 1. The parameter maxextents speci es the admissible number of extents. The parameter
3. The modi cations of the tuples a ected by the update occurs in the database bu er. pctincrease speci es the percent by which each extent after the second grows over the previous
Before the data blocks are modi ed, the \before image" of the tuples is written to the extent. The default value is 50, meaning that each subsequent extent is 50% larger than
rollback segments by the DBWR process. the preceding extent. Based on the above table de nition, we thus would get the following
logical database structure for the table STOCKS (assuming that four extents have already been
4. While the redo-log bu er is lled during the data block modi cations, the LGWR process allocated):
writes entries from the redo-log bu er to the redo-log les.
initial 1M 400k 600k 900k
5. After all tuples (or rather the corresponding data blocks) have been modi ed in the
database bu er, the modi cations can be committed by the user using the commit 1. Extent 2. Extent 3. Extent 4. Extent
command.
6. As long as no commit has been issued by the user, modi cations can be undone using Figure 6: Logical Storage Structure of the Table STOCKS
the rollback statement. In this case, the modi ed data blocks in the database bu er are
overwritten by the original blocks stored in the rollback segments. If the space required for a database object is known before creation, already the initial extent
7. If the user issues a commit, the space allocated for the blocks in the rollback segments is should be big enough to hold the database object. In this case, the Oracle server (more
deallocated and can be used by other transactions. Furthermore, the modi ed blocks in precisely the resource manager) tries to allocate contiguous data blocks on disks for this object,
the database bu er are unlocked such that other users now can read the modi ed blocks. thus the defragmentation of data blocks associated with a database object can be prevented.
The end of the transaction (more precisely the commit) is recorded in the redo-log les. For indexes a storage clause can be speci ed as well
The modi ed blocks are only written to the disk by the DBWR process if the space
allocated for the blocks is needed for other blocks.
create index STOCK IDX on STOCKS(ITEM)
storage (initial 200k next 100k
6.5 Creating Database Objects minextents 1 maxextents 5);
For database objects (tables, indexes, clusters) that require their own storage area, a segment
in a tablespace is allocated. Since the system typically does not know what the size of the
63 64

You might also like