INTRO TO ORACLE 
ORACLE9i Intro to SQL and PL/SQL
COURSE DESCRIPTION
This course offers students a lecture/lab intensive environment on Oracle's Data Server
Technology. The class covers the concepts of both relational and object relational databases
and the use of SQL. The student will learn how to write simple to complex queries along with
being able to modify database objects through SQL. Advanced technique such as ROLLUP,
CUBE, set operators and creation of user-defined datatypes discussed.
AUDIENCE:
Application Developers
Database Administrators
Systems Analysts
Technical Support Professionals
PREREQISITES:
Working knowledge of computers
HARDWARE/SOFTWARE REQUIREMENTS:
Hardware
Minimal processor speed of 266 mhz or higher
Memory requirements - 128 mb
Video: 16 color (800 x 600 resolution minimum)
50 mb of storage space per student
Software
MS Windows 95/98/2000/NT 4.0/ME or UNIX/LINUX
Oracle version 8.05 or higher installed.
User id's for both the operating system and Oracle which have
At minimum Connect and Resource privilege.
COURSE OBJECTIVES
The student upon completion of this course will be able to:
 Create, Retrieve and Manipulate database objects
 Utilize PL/SQL to control transactions
 Understand relational versus object database concepts
 Identify when to use joins, subqueries or set operators
 Utilize BASIC SQL with SQL*PLUS
 Use SQL*PLUS formatting commands
 Use the new single-row DATETIME and NVL2 function of 9i
 Utilize SQL ANALYZE to evaluate SQL statements for efficiency
======================================================
TABLE OF CONTENTS 
1. INTRODUCTION TO ORACLE & SQL*PLUS
OBJECTIVES
A. ORACLE signing on to SQL*PLUS.................................................2
B. ORACLE SQL*PLUS commands.....................
........
.
...3-6
C. ORACLE SQL*PLUS Editing Commands...............................
...7
D. ORACLE scripts...........................................................................
..8
E. Data Dictionary tables
...9
F. Future Directions
.10
G. Database Development
..12
H. SQL*PLUS Programming Commands
15-17
I. SQL*PLUS Reporting Commands
18
J. Query Enhancement Commands
..
19-20
K. Other SQL*PLUS Commands
.
..20-22
II BASIC SQL LANGUAGE
OBJECTIVES
A. Understanding the SQL Format ....................................................3-5
B. Querying Row and Columns ..........................................................6-7
C. Using the Where clause ..............................................................8-18
D. Accessing tables with compound statements .........................19-28
E. Utilizing Built-In Functions ..........................................................29-32
F. Using Group By, Rollup and CUBE
..
.
33-35
G.. Searching for Null values ...........................................................36-43
III. ADVANCED SQL LANGUAGE
OBJECTIVES
A. Accessing tables through Joins ...................................................2-7
B. Understanding the use of Outer Joins ........................................
8
C. Comprehending Subqueries ...................................................12-17
D. Selecting rows using Union, Intersect and Minus ......
18-22
E. Modifying data through Inserts,Updates and Deletes ...........23-31
============================================
ORACLE9I Intro to SQL and PL/SQL
TABLE OF CONTENTS
IV. SQLPLUS COMMANDS
OBJECTIVES
A. Setting Column Widths ...................................................................2
B. Setting Numeric Edit patterns ........................................................3
C. Understanding Character Functions
.....
.4
D. Understanding Dates
...
5
E. Using DateTime functions
.
...8
F. SQL*PLUS extensions with built-in functions ...........................8-10
V. DATA DEFINITION LANGUAGE
OBJECTIVES
A. Creating base tables ...................................................................2-5
B. Using ORACLE datatypes ..........................................................6-7
C. Creating Oracle Objects
...
8-9
D. Table Constraints
....
...10-14
E. Creating Sequences
....
..15-17
F. Building Indexes for base tables ..............................................18-29
G. Creating Synonyms .........................................................................31
H. Creating Views for Users .....................................................
.33-41
VI. PL/SQL
OBJECTIVES
A. Introduction to PL/SQL ................................................................1-19
B. Processing in the PL/SQL environment ..................................20-27
C. Control Flow Language..........................................................
28-29
D. Iterative Processing (LOOPS)
.....
.29-33
E. Exception Processing
....34-42
F. Cursor Processing
.................................................................43-55
VII. SQL ANALYZE
OBJECTIVES
A. Understanding and Using Oracle Tuning Pack
......
.1-6
B. Using SQL ANALYZE to identify SQL efficiency.......................7-10
C. Comparing different queries on the same screen
...
....11-13
D. Generating Index hints and recommendations
...
.14-18
APPENDIX
VIII DATABASE MODELING
OBJECTIVES
A. E/R Modeling techniques .........................................................
B. Normalization ...........................................................................
C. Referential Integrity Constraints ..............................................
===============================================================
INTRODUCTION TO ORACLE - Chapter 1
TOPIC OBJECTIVES
This section introduces the architecture of Oracle and the reasons for using the ORACLE
database. When you finish this section, you will be able to:
 Identify the basic architecture of the ORACLE database
 Comprehend the different user roles in the ORACLE database
 Understand the different directories used by the ORACLE database
 Recognize the different GUI interfaces and utilities available in ORACLE
===================================================
LOGGING INTO SQL*PLUS
You can see the SGA by logging into ORACLE'S SQL*PLUS front-end. To log in, select START/PROGRAMS/ORACLE for WindowsNT/SQLPLUS8.0 or SQLPLUS3.3. A hostname
is necessary when connecting to a non-local database.
Sign in with the standard Database Administrator ID of SYSTEM and a password
of MANAGER.
=============================================================
A SIMPLE SELECT
 A select retrieves data (rows) from a table. In SQL*PLUS it is
necessary to end each SQL statement with a semi-colon in
order to execute a SQL statement as shown above.
 When typing a SQL statement directly in SQL*PLUS, the
SQL statement is placed in a memory buffer called afiedt.buf.
 To edit a SQL statement you have typed into the buffer
(afiedt.buf) type EDIT at the prompt. In WIN95, WIN98, & NT
the notepad editor will automatically show you what is in the
afiedt.buf file.
 To save any changes you have made, click on File & save or File
& SaveAs. You may also use the dos command of ALT F and then S
to save your changes.
================================================
ORACLE FILE EXTENSIONS
The files with the extension of sql are SQL command files. They contain SQL commands.
These sql statements are executable within SQLPlus.
Any SQL statement you type in SQL*PLUS may be saved to a file in your current working
directory. To identify your current directory where files will be saved:
 Type in HOST to go to the PROMPT.
 To return to SQL*PLUS type in EXIT.
 To save the SQL Statement select * from v$sga, you would type in SAVE sga at the SQL
prompt in SQL*PLUS. This SQL statement reads rows from a table called V$SGA.
 Type in HOST to go back to the Operating system PROMPT.
 Type in DIR SG*.* (or ls sg* in UNIX) to see that the SGA file you just created has an
extension of .SQL
======================================================
SAVING A SQL STATEMENT TO A FILE
Anything SQL statement you saved to a file in your your current working directory maybe
retrieved with a GET statement.
 From the SQL prompt type in get sga. Oracle automatically looks for any file called sga.sql.
If it can find the file it puts the information into the afiedt.buf file and displays the SQL
information from the file on the SQL*PLUS screen.
 To run a SQL statement in the current buffer (afiedt.buf) just type in a forward slash / as
shown above.
 You can run a script (file) in your current directory without doing a get, just type in @sga from
the SQL*PLUS prompt. This will find the file in your current directory and run it.
===========================================================
CRT FILES AND SPOOL FILES
The crt files are the various CRT drivers that you can use and the lst files are list files.
Spool commands in SQL*PLUS always have the extension of *.LST. If you wanted to send the
output to a connected printer you could use the SPOOL OUTcommand.
=========================================================
USING ORACLE SQL*PLUS EDITING COMMANDS
Oracle has it's own line editor. It can be useful when small changes or editions need to be
made to a SQL statement.
=======================================================
SQL SCRIPTS
To execute a script not in your current directory you can provide a
fully qualified path as shown below.
ORACLE> @c:\orant\bin\demobld
(Notice that SQLPLUS looks for a file called demobld.sql. The sql extension is
the default for files).
 This script builds test tables for you to practice queries on and loads the
tables with data.
 Oracle lets you see all the objects you own or can use by reading the TAB view
 To see all the tables and objects that the username SYSTEM has access to, type
in the following SQL statement:.
ORACLE> SELECT * FROM TAB;
You can also execute SQL*PLUS commands that provide you with a variety of
information such as your current username (who you logged in as) as seen below.
ORACLE> SHOW USER
===================================================
DICTIONARY TABLES FOR USERS
The Dictionary VIews these views provide you with information on objects
created in the database:
USER_TABLES
USER_TABLESPACES
USER_INDEXES
The dictionary views below show you information concerning users of this
database and other objects which a user may have access to.
ALL_USERS
USER_CONSTRAINTS
DBA_PASSWORDS
The following query show the information concerning ALL users in the current database.
ORACLE> select * from ALL_USERS;
Oracle allows you to specify the level of granularity on what objects you would like to see.
DBA, ALL, or USER
If you are a DBA you can retrieve information from any table that starts with DBA. For example, if we wanted to retrieve information from an Oracle Data Dictionary table called DBA_TABLES, we could write a query as shown below.
ORACLE> SELECT TABLESPACE_NAME,
TABLE_NAME,
NUM_ROWS,
BLOCKS
FROM DBA_TABLES
Now save this SQL statement as usrtab1. ORACLE> SAVE USRTAB1
=================================================================
FUTURE DIRECTIONS
PLAN for future growth.
 Understand how to design and develop the database applications.
 Be able to estimate storage requirements for applications.
 Tune the application during development
MANAGERS
Managers must develop a team with the proper expertise.
Knowledge needed by the analyst includes:
 This person should know about E/R Modeling, Normalization, and the application.
 Programmers/Analysts must be available to build the applications.
 They must know how to use Oracle and its utilities.
 Also, they should have a knowledge of either 'C', `C++',or 'Cobol'.
 A Database Administrator must be someone who can implement the Oracle system, and be responsible for security, integrity and backup and recovery of the Oracle databases.
===========================================================
PROGRAMMERS/ANALYSTS
A programmer/analyst must learn to design an Oracle database and
assist in implementing the database using SQL for the logical, physical and application definition activities.
The programmer/analyst must learn how to use Oracle's development tools :
 SQL*PLUS/BROWSER
 ORACLE FORMS
 ORACLE Reports
 PL/SQL-PRO*C products
 SQL*LOADER
Finally, the programmer must know how to do embedded programming either
with Pro*C or Pro*Cobol or use CASE tools such as Powertool or
Powerbuilder.
=======================================================
BENEFITS OF DATABASE DEVELOPMENT
End-User Development
In today's database development, by virtue of having sophisticated relational database management systems, users will have easy interfaces into the data.
For example, query ability is provided by Oracle using:
 Structured Query Language (SQL) under SQL*PLUS, ORACLE Reports to allow end users to create comprehensive reports.
 Browser which allows for the user friendly access to Oracle tables.
 Front ends such as Visual Basic and Access can be used to query ORACLE as well.
============================================================
LAB 1 - Running Oracle and Building Demo Tables
This exercise is designed to get you familiar with the ORACLE SQL*PLUS environment
and reviewing ORACLE scripts.
1. Log off from SQL*PLUS by typing in exit from the SQL*PLUS prompt. Log
back in as System username and a password of Manager.
2. Find out what your current home directory is and write the path name below.
Check to see if you have a file called demobld.sql. Open this script up with
an editor and review the contents of the file. Does this file contain
more than one SQL statement.
____________________________________________________
NOTE You can edit a query by exiting to the host system. This is done by
Typing in the command HOST. This will display a UNIX or Windows
prompt where you can then edit the file called demobld.sql to
review the SQL statements in this script.
3. Once finished reviewing the demobld.sql script you may return to
SQL*PLUS by typing exit at the prompt.
4. When you return from reviewing the demobld.sql script you can execute
the script in SQL*PLUS by typing @demobld or by start demobld.
Why can't you execute this script by doing a GET and then a /?
When finished you have created many different tables, to see the new tables
type in: @usrtab1
To see what columns are in each table, use the describe command:
desc staff
desc org
desc applicant
====================================================
SQL*PLUS COMMANDS
SQL*PLUS commands are unique to Oracle. There may be classified as:
Editing, Programming, Reporting, Query Enhancement and Other types of commands.
Let's use the USRTAB1 script we created earlier and edit this script in the buffer.
EDITING COMMANDS
/* From SQL*PLUS, type in get usrtab1 . The following script will be displayed. */
ORACLE> SELECT TABLESPACE_NAME,
TABLE_NAME,
NUM_ROWS,
BLOCKS
FROM DBA_TABLES
INPUT adds new lines after the current line in the current buffer.
/* To add a new line to the USRTAB1 script use the INPUT command.
ORACLE> I
6 WHERE TABLE_NAME = `STAFF'
. /* When a return is done after `STAFF' another new line appears. Type in
a period ( . )a return. */
ORACLE> / /* a forward slash executes the new script */
ORACLE>save usrtab1 replace /* Replaces the a file which exists with the
statement in the buffer */
DEL will delete the current line in the command buffer.
/* To del the line we just added: */
ORACLE> DEL OR DEL 6
APPEND adds text to the end of the current line in the buffer.
/* To append where table_name = `STAFF' to line 5, type in the following: */
ORACLE> A WHERE TABLE_NAME = `STAFF'
LIST lists lines in the current buffer.
/* To change the focus of an ORACLE editor to another line other than the last
line, type in the following command: /*
l4
BLOCKS
CHANGE changes the contents of the current buffer.
/* To use the change command on line 4 above, to change BLOCKS TO
INITIAL_EXTENT, do the following:
c/BLOCKS/INITIAL_EXTENT/
EDIT invokes the host system text editor on the contents of the
current buffer or file.
ORACLE> EDIT -- Show the current SQL command in the buffer in
NOTEPAD.
======================================================
PROGRAMMING COMMANDS
ACCEPT Requests input through a blinking cursor and places
response in a user variable.
ORACLE> ACCEPT local_id
10 -- Key in the number 10 after pressing return above.
Select * from staff where dept = &local_id;
DEFINE defines a user variable and assigns it a value.
ORACLE> DEFINE -- SHOWS YOU ALL VARIABLES
YOU HAVE DEFINED
PROMPT issues a prompt on the screen.
ORACLE> ACCEPT VAR1 PROMPT `ENTER A VALUE OF'
ENTER A VALUE OF URNAME
/* VAR1 NOW HAS A VALUE OF URNAME */
========================================================
PROGRAMMING COMMANDS CONTINUED
BREAK specified the events causing a break and the actions to be
done. Used with select statements which have an order by clause.
ORACLE> BREAK ON DEPT
ORACLE> SELECT * FROM STAFF ORDER BY DEPT;
/* Notice that the department numbers only print out one
time. */
PAUSE displays a message, then waits for the user to press [return].
ORACLE> SET PAUSE ON
RUN displays and runs the command in the current buffer.
ORACLE> RUN USRTAB1
=======================================================
PROGRAMMING COMMANDS CONTINUED
SAVE saves the contents of the current buffer in an operating
system file.
ORACLE> SAVE NEWSCRIPT
START executes the contents of a command file.
ORACLE> START USRTAB1
UNDEFINE deletes a user variable definition.
ORACLE> UNDEFINE LOCAL_ID
SET sets an SQL*PLUS system variable to a specified value.
ORACLE> SET VERIFY OFF
ORACLE> SET HEADING OFF
========================================================
REPORTING COMMANDS
BTITLE displays a title at the bottom of each report page.
COLUMN specifies a column heading and format in a report.
ORACLE> COLUMN ID HEADING EMPNO - CHANGES ID heading to EMPNO
ORACLE> COLUMN SALARY FORMAT $99,999.99
/* Any salary column in any table know has a $ sign, 7digits and 2
decimal positions.*/
TTITLE displays a title at the top of each report page.
ORACLE> TTITLE `MY STAFF REPORT'
/* Every page of the report will have the Central heading of MY
STAFF REPORT */
========================================================
PROGRAMMING COMMANDS CONTINUED
QUERY ENHANCEMENT COMMANDS
COMMIT makes all database changes permanent.
UPDATE STAFF
SET SALARY = 90000
WHERE ID = 290;
COMMIT;
SELECT * FROM STAFF WHERE ID = 290;
ROLLBACK discards changes made to a database since the last
ORACLE> UPDATE STAFF
SET SALARY = 77000
WHERE DEPT = 10;
ORACLE> SELECT * FROM STAFF
WHERE DEPT = 10;
/* Notice that all salaries in department 10 are set to 77000.
No one but the person updating these rows can see the
changed data. It must be committed in order to see it.
ORACLE> ROLLBACK
ORACLE> SELECT * FROM STAFF
where dept = 10; -- The data is back to its original state.
======================================================
PROGRAMMING COMMANDS CONTINUED
COMPUTE performs computations on groups of rows selected by a
query.
ORACLE> compute sum of salary on dept
/* Sub Totals on salary for each department are displayed.*/
DESCRIBE table displays a brief description of a table.
=====================================================
OTHER COMMANDS
@file similar to the START command.
Oracle> @usrtab1
/ runs the command in the SQL buffer. This is similar to the RUN command.
CLEAR clears break definitions, buffers, column definitions, etc.
ORACLE> CLEAR SCREEN
ORACLE> CLEAR COLUMNS
ORACLE> CLEAR BREAK
CONNECT disconnects the current user name and reconnects with the connect name.
ORACLE> CONNECT SYSTEM/MANAGER
ORACLE> CONNECT SCOTT/TIGER
COPY copies data to, from or between Oracle databases. SQLNET command.
DISCONNECT commits work, disconnects the current user name but remains
in SQL*PLUS.
EXIT leaves SQL*PLUS, disconnects the user and commits work.
GET loads a file into the current buffer.
ORACLE> GET USRTAB1
HELP displays help information.
/* CLICK ON HELP MENU ON WINDOWS MENU
======================================================
OTHER COMMANDS
HOST executes a host operating system command without leaving
SQL*PLUS.
SHOW displays the setting of a SQL*PLUS system variable.
Oracle> show all
SPOOL directs displayed output to a system file or printer.
TIMING records timing data for an elapsed period of time.
====================================================
LAB 2 - Utilizing ORACLE commands using SQL*PLUS
Simple Report Formatting - SQL*PLUS Commands for Reporting
1. Some SQL*PLUS Commands may be used to format the results of SQL queries.
2. The COLUMN Command may be used to change column headings. The
following will cause a permanent report heading change for the current
SQL*PLUS session.
SELECT * FROM EMP WHERE MGR
= 7698;
COLUMN DEPTNO HEADING DEPARTMENT ;
RUN
The COLUMN Command may also be used to change column output formats.
The FORMAT keyword may also be used to change the display format width
of a column.
COLUMN SAL FORMAT $9999.99 ;<R>
COLUMN COMM FORMAT $9999.99 ;<R> RUN
4. A report title may be added using the TTITLE Command. The HEADSEP
character | is used to start a new line.
TTITLE 'WILLIAM BLAKE|LIST OF EMPLOYEE';
RUN
=======================================================
SQL*PLUS Commands
Special SQL*PLUS Commands
Storing and printing results may be done using the SPOOL Command. The SPOOL
FILE command can be found under the FILE column in SQL*PLUS. Click on SPOOL
FILE and you will be prompted for the output SPOOL FILENAME. When you have finished
spooling your output to the file you turn of spooling by clicking on the SPOOL OFF
command under the FILE column in SQL*PLUS. As an alternative you may key in the
SPOOL commands as shown below.
- To begin spooling output to a file, type the name of a file after the SPOOL Command.
- To close and print a file, use the SPOOL OUT.
- SPOOL OFF will stop spooling and not print the file.
SELECT DEPTNO, ENAME, SAL FROM
EMP
WHERE DEPTNO = 10
ORDER BY SAL DESC ;
SPOOL TEMP ;
RUN
SPOOL OUT ; /* sends your output to the connected printer */
SPOOL OFF; /* sends your output to the spooled file */
2. Try the following examples of saving and retrieving commands.
L /* List contents of buffer */
SAVE SALARY; /* Saves contents of the buffer to SALARY */
CLEAR BUFFER ; /* Clears the buffers */
GET SALARY ; /* Puts contents of SALARY in buffer */
L /* Verifies contents of buffer */
R /* Runs commands in buffer */
CLEAR BUFFER ; /* Clear buffer again */
START SALARY; /* Gets and runs commands in SALARY */
L3 /* Lists third line */
C/10/&1/ /* Changes DEPTNO value to a parameter */
L /* Verify change */
SAVE SALARY REPLACE ;
START SALARY 20 /* Runs commands for DEPTNO = 20 */
STRUCTURED QUERY LANGUAGE - Chapter 2
TOPIC OBJECTIVES
This section introduces the ANSI standard SQL statements as used in ORACLE.
When you finish this section, you will be able to:
 Understand the standard ANSI SQL available in ORACLE
 Comprehend the SQL*PLUS environment for executing SQL statements
 Identify the basic format and structure of the SQL statements
 Write SQL Select statements to retrieve multiple rows and/or columns
 Be able to write SQL commands utilizing the where clause, group by, having and order by verbs.
SQL Components
TABLE ACCESS METHODS
SQL Data Manipulation Language (DML)
RETRIEVAL
|
BUILT-IN FUNCTIONS
|
ARITHMETIC OPERATORS
|
SELECT
|
MIN
MAX
SUM
AVERAGE
COUNT
|
+
-
/
*
|
GROUPING
|
OTHER OPERATORS
|
COMPARISON OPERATORS
|
GROUP BY
HAVING
|
LIKE
DISTINCT
ANY
ALL
IN
BETWEEN
UNION
AND
OR
NOT
|
=
<>
<
>
|
MODIFICATIONS
|
SEQUENCING
|
 |
INSERT
DELETE
UPDATE
|
ORDER BY
|
 |
 |
 |
 |
Sample Tables
ORG
DEPTNUMB
|
DEPTNAME
|
MANAGER
|
DIVISION
|
LOCATION
|
10
|
HEAD OFFICE
|
160
|
CORPORATE
|
NEW YORK
|
15
|
NEW ENGLAND
|
050
|
EASTERN
|
BOSTON
|
20
|
MID ATLANTIC
|
010
|
EASTERN
|
WASHINGTON
|
38
|
SOUTH ATLANTIC
|
030
|
EASTERN
|
ATLANTA
|
42
|
GREAT LAKES
|
100
|
MIDWEST
|
CHICAGO
|
51
|
PLAINS
|
140
|
MIDWEST
|
DALLAS
|
66
|
PACIFIC
|
270
|
WESTERN
|
SAN FRANCISCO
|
84
|
MOUNTAIN
|
290
|
WESTERN
|
DENVER
|
APPLICANT
TEMPID
|
NAME
|
ADDRESS
|
EDLEVEL
|
COMMENTS
|
40
|
FROMMHERZ
|
SAN JOSE, CA
|
12
|
NO SALES EXP.
|
410
|
JACOBS
|
POUGHKEEPSIE, NY
|
16
|
GOOD CAND./DC
|
420
|
MONTEZ
|
DALLAS, TX
|
13
|
OFFER SALES POS..
|
430
|
RICHOWSKI
|
TUCSON,AZ
|
14
|
CAN''T START WORK UNTIL 12/93
|
440
|
REID
|
ENDICOTT, NY
|
14
|
1 YEAR SALES EXP.
|
450
|
JEFFYREYS
|
PHILADELPHIA, PA
|
12
|
GOOD CLERICAL BACKGROUND
|
460
|
STANLEY
|
CHICAGO, IL.
|
11
|
WANTS PARTTIME JOB
|
470
|
CASALS
|
PALO ALTO. CA
|
14
|
EXPERIENCED SALES
|
480
|
LEEDS
|
EAST FISHKILL, NY
|
12
|
NEEDS INTERVIEW WITH BROWN
|
490
|
GASPARD
|
PARIS, TX
|
16
|
WORKED HERE 1-80
|
STAFF
ID
|
NAME
|
DEPT
|
JOB
|
YEARS
|
SALARY
|
COMM
|
10
|
SANDERS
|
20
|
MGR
|
7
|
18357.50
|
---
|
20
|
PERNAL
|
20
|
SALES
|
8
|
18171.25
|
612.45
|
30
|
MARENGHI
|
38
|
MGR
|
5
|
17506.75
|
---
|
40
|
O'BRIEN
|
38
|
SALES
|
6
|
18006.00
|
846.55
|
50
|
HANES
|
15
|
MGR
|
10
|
20659.80
|
---
|
60
|
QUIGLEY
|
38
|
SALES
|
--
|
16808.30
|
650.25
|
70
|
ROTHMAN
|
15
|
SALES
|
7
|
16502.83
|
1152.00
|
80
|
JAMES
|
--
|
CLERK
|
--
|
13504.60
|
128.20
|
90
|
KOONITZ
|
42
|
SALES
|
6
|
18001.75
|
1386.70
|
100
|
PLOTZ
|
42
|
MGR
|
7
|
18352.80
|
---
|
110
|
NGAN
|
15
|
CLERK
|
5
|
12508.20
|
206.60
|
120
|
NAUGHTON
|
38
|
CLERK
|
--
|
12954.75
|
180.00
|
130
|
YAMAGUCHI
|
42
|
CLERK
|
6
|
10505.90
|
75.60
|
140
|
FRAYE
|
51
|
MGR
|
6
|
21150.00
|
---
|
150
|
WILLIAMS
|
51
|
SALES
|
6
|
19456.50
|
637.65
|
160
|
MOLINARE
|
10
|
MGR
|
7
|
22959.20
|
---
|
170
|
KERMISCH
|
15
|
CLERK
|
4
|
12258.50
|
110.10
|
180
|
ABRAHAMS
|
38
|
CLERK
|
3
|
12009.75
|
236.50
|
190
|
SNEIDER
|
20
|
CLERK
|
8
|
14242.75
|
126.50
|
200
|
SCOUTTEN
|
42
|
CLERK
|
--
|
11508.60
|
84.20
|
210
|
LU
|
10
|
MGR
|
10
|
20010.00
|
---
|
220
|
SMITH
|
51
|
SALES
|
7
|
17654.50
|
992.80
|
230
|
LUNDDQUIST
|
51
|
CLERK
|
3
|
13369.80
|
189.65
|
240
|
DANIELS
|
10
|
MGR
|
5
|
19260.25
|
---
|
250
|
WHEELER
|
51
|
CLERK
|
6
|
14460.00
|
513.30
|
260
|
JONES
|
10
|
MGR
|
12
|
21234.00
|
---
|
270
|
LEA
|
66
|
MGR
|
9
|
18555.50
|
---
|
280
|
WILSON
|
66
|
SALES
|
9
|
18674.50
|
811.50
|
290
|
QUILL
|
84
|
MGR
|
10
|
19818.00
|
---
|
300
|
DAVIS
|
84
|
SALES
|
5
|
15454.50
|
806.10
|
310
|
GRAHAM
|
66
|
SALES
|
13
|
21000.00
|
200.30
|
320
|
GONZALES
|
66
|
SALES
|
4
|
16858.20
|
844.00
|
330
|
BURKE
|
66
|
CLERK
|
1
|
10988.00
|
55.50
|
340
|
EDWARDS
|
84
|
SALES
|
7
|
17844.00
|
1285.00
|
350
|
GAFNEY
|
84
|
CLERK
|
5
|
13030.50
|
188.00
|
SQL Basic Retrieval
Task: Produce a list of all information in TABLE ORG
SQL:
SELECT DEPTNUMB,DEPTNAME,MANAGER,DIVISION,
LOCATION from ORG
or
SELECT * FROM ORG
RESULT:
DEPTNUMB
|
DEPTNAME
|
MANAGER
|
DIVISION
|
LOCATION
|
10
|
HEAD OFFICE
|
160
|
CORPORATE
|
NEW YORK
|
15
|
NEW ENGLAND
|
50
|
EASTERN
|
BOSTON
|
20
|
MID ATLANTIC
|
10
|
EASTERN
|
WASHINGTON
|
38
|
S. ATLANTIC
|
30
|
EASTERN
|
ATLANTA
|
42
|
GREAT LAKES
|
100
|
MIDWEST
|
CHICAGO
|
51
|
PLAINS
|
140
|
MIDWEST
|
DALLAS
|
66
|
PACIFIC
|
260
|
WESTERN
|
SAN FRANCISCO
|
84
|
MOUNTAIN
|
290
|
WESTERN
|
DENVER
|
MODEL SELECT STATEMENT
SELECT (DISTINCT) ITEMS
FROM TABLE NAMES
{WHERE CONDITIONS}
{GROUP BY COLUMNS {HAVING CONDITIONS} }
{ORDER BY COLUMNS}
SQL Basic Retrieval
TASK: Get all information pertaining to departments assigned to the eastern division
SQL:
SELECT * FROM ORG
WHERE DIVISION='EASTERN'
RESULT:
DEPTNUMB DEPTNAME MANAGER DIVISION LOCATION
----------------- ------------------ ---------------- --------------- ------------------
15 NEW ENGLAND 50 EASTERN BOSTON
20 MID ATLANTIC 10 EASTERN WASHINGTON
38 SOUTH ATLANTIC 30 EASTERN ATLANTA
NOTES:
1. Values to be compared with columns of character data must be enclosed in single quotes (DIVISION='EASTERN')
2. Values to be compared with columns of numeric data must not be In quotesUsing inequalities in the WHERE clause
= (equal to)
^ = (not equal to)
> (greater than)
>= (greater than or equal to)
< (less than)
<= (less than or equal to)
 Search conditions may contain any of the above
 Numbers compare algebraically, meaning negative numbers are less than positive numbers regardless of absolute value
 If comparing two character strings of different lengths, the shorter is padded at the right with blanks to make it the same length
SQL Basic Retrieval
TASK: List all employees with more than 10 years with the company
SQL:
SELECT * FROM STAFF
WHERE YEARS> 10
RESULT:
ID NAME DEPT JOB YEARS SALARY COMM
-------- ----------------- ---------- --------------- --------- --------------- -------------
260 JONES 10 MGR 12 21234.00 ---
310 GRAHAM 10 SALES 13 21000.00 200.30
Exercises: (Use the ORG, STAFF OR APPLICANT TABLES)
1. Get all the employees who made more than $1000 commission.
See ex11.sql
2. Get all the employees who make no more than $15,000 salary
(Ignore commission). See ex12.sql
3. Get all the employees who are not clerks. See ex13.sql
Selecting Specific Columns
TASK: Get the names and IDs of all employees who are managers
SQL:
SELECT ID, NAME
FROM STAFF
WHERE JOB='MGR'
RESULT:
ID NAME
------ -----------
10 SANDERS
30 MARENGHI
40 HANES
100 PLOTZ
140 FRAYE
160 MOLINAIRE
210 LU
240 DANIELS
260 JONES
270 LEA
290 QUILL
Retrieval of Computed Values
TASK: Get the monthly salary of all CLERKS in department 38
SQL:
SELECT NAME, SALARY/12
FROM STAFF
WHERE JOB = `CLERK' AND DEPT=38
RESULT:
NAME SALARY/12
------------------- ----------------------
NAUGHTON 1079.56
ABRAHAMS 1000.81
NOTES:
1. Computed values, or expressions, make use of the standard operations:
+ ADD
- SUBTRACT
* MULTIPLY
/ DIVIDE
SQL RETRIEVAL EXAMPLES:
1. Give names of all managers making less than $20,000. See ex21.sql
2. For all employees in department 66, give their name, job function and total
annual earnings (Salary and Commissions). See ex22.sql
3. Give the name and department number of each employee not in department 15. See ex23.sql
4. List all information about employee IDs up to and including 100. See
ex24.sql
Order by Clause
SELECT DEPT, NAME, ID, SALARY
FROM STAFF
ORDER BY DEPT, SALARY DESC
 The order by clause describes the order of the query result
 All columns in the order by clause must also be in the select clause
 Ordering may be ascending or descending on any one field
 Cannot use expressions in the order by clause as an ANSI standard.
NOTE: Oracle will allow you to use expressions.
Ordering by Descending
TASK: Give the employee ID, name, and department for each manager.
Order the result in descending years of service
SQL:
SELECT ID, NAME, DEPT, YEARS
FROM STAFF
WHERE JOB='MGR'
ORDER BY YEARS DESC
RESULT:
ID NAME DEPT YEARS
--------- ------------------------ ---------- ------------
260 JONES 10 12
310 HANES 15 10
210 LU 10 10
290 QUILL 84 10
270 LEA 66 10
10 SANDERS 22 7
100 PLOTZ 42 7
160 MOLINAIRE 10 7
140 FRAYE 51 6
30 MARENGHI 38 5
240 DANIELS 10 5
Ordering by column numbers
TASK:Get the name and monthly salary of each employee in Department 38. Order the output by descending monthly salary
SQL:
SELECT NAME, SALARY/12
FROM STAFF
WHERE DEPT=38
ORDER BY 2 DESC
RESULT:
NAME SALARY/12
------------------- ----------------------
O'BRIEN 1500.50
MARENGHI 1458.90
QUIGLEY 1400.69
NAUGHTON 1079.56
ABRAHAMS 1000.81
NOTES:
Necessary for expressions, since expressions cannot appear in the order by clause
The distinct operand
Case A: Without the distinct operand
SQL:
SELECT EDLEVEL FROM APPLICANT
RESULT:
EDLEVEL
--------------
12
16
13
14
14
12
11
14
12
16
Case B: With the distinct operand
SQL:
SELECT DISTINCT EDLEVEL
FROM APPLICANT
RESULT:
EDLEVEL
11
12
13
14
16
Selecting On Conditions
Other conditional clauses
Multiple conditions And, Or, and ( )
Values in a range Between X and Y
Values from a list In (X, Y, Z)
Partial search values Like '%ABC%'
Like `_A_'
Negative conditions Not
Checking for nulls Is Null
Multiple Conditions
TASK: Get the ID, Name, and Department for each manager making more
than $21,000
SQL:
SELECT ID, NAME, DEPT
FROM STAFF
WHERE JOB = 'MGR' AND SALARY > 21000
RESULT:
ID NAME DEPT
--------- ------------------------ ----------
140 FRAYE 51
160 MOLINAIRE 10
260 JONES 10
Multiple Condition ExERCISES
1) Get the name of each employee who is either a manager or who has over
10 years seniority. See ex31.sql
2) Display the ID, name, and total earnings of each clerk who earned between
12,000 and $15,000 salary in addition to at least $150 commission. See
ex32.sql
3) Display all department numbers having at least one employee with more
than 5 years experience and making less than $15,000. See ex33.sql
The Between Clause
TASK: Get the name of each employee with from 3 to 5 years of service
SQL:
SELECT NAME FROM STAFF
WHERE YEARS BETWEEN 3 AND 5
RESULT:
NAME
------------
MARENGHI
NGAN
KERMISCH
ABRAHAMS
LUNDQUIST
DANIELS
DAVIS
GONZALEZ
GAFNEY
NOTES:
Limits are inclusive
The in clause
TASK: Get the name and address of each applicant who's education level
is 11, 12, or 16
SQL:
SELECT NAME, ADDRESS
FROM APPLICANT
WHERE EDLEVEL IN (11, 12, 16);
RESULT:
NAME ADDRESS
------------ ---------------
FROMMHERZ SAN JOSE, CA
JACOBS POUGHKEEPSIE, NY.
JEFFYREYS PHILADELPHIA, PA.
STANLEY CHICAGO, IL.
LEEDS EAST FISHKILL, NY.
GASPARD PARIS, TX.
The Like Clause
TASK: Display the department number and department name for each
department that has the string "ATLANTIC" embedded somewhere
in the department name
SQL:
SELECT DEPTNUMB, DEPTNAME
FROM ORG
WHERE DEPTNAME LIKE '%ATLANTIC%'
RESULT:
DEPTNUMB DEPTNAME
------------------ -----------------
20 MID ATLANTIC
38 SOUTH ATLANTIC
NOTES:
1) The percent sign (%) stands for any number of characters, or none
2) The % may appear before the string, after the string, or both
THE LIKE CLAUSE
TASK: List the name of each employee whose name contains the
characters 'ON' in the second and third position
SQL:
SELECT NAME FROM STAFF
WHERE NAME LIKE '__ON%'
RESULT:
NAME
---------
JONES
GONZALEZ
NOTES:
1) Each underscore (not hyphen) represents exactly one character
2) The like clause is only valid with character data
THE LIKE CLAUSE EXERCISES
1) Display the department name and manager id (from org table) of each department whose location ends with the characters "TON". See ex41.sql
2) Display all department names that contain the characters "AIN" anywhere
after the first character. See ex42.sql
3) Display all employee names that begin with "S" and contain at least one "D"
See ex43.sql
Negative Conditions
The opposite of any condition can be indicated by placing "NOT" in front of it:
SQL:
SELECT DEPTNUMB, DEPTNAME
FROM ORG
WHERE DEPTNUMB NOT BETWEEN 15 AND 66
RESULT:
DEPTNUMB DEPTNAME
------------------ -----------------
10 HEAD OFFICE
84 MOUNTAIN
SQL:
SELECT ID, NAME
FROM STAFF
WHERE ID BETWEEN 200 AND 230
AND NAME NOT LIKE 'S%'
RESULT:
ID NAME
--- -----------
210 LU
230 LUNDQUIST
Negative Conditions
Case A:
SELECT DEPTNUMB, DEPTNAME
FROM ORG
WHERE NOT DEPTNUMB > 15
AND DIVISION = 'EASTERN'
RESULT:
DEPTNUMB DEPTNAME
15 NEW ENGLAND
Case B:
SELECT DEPTNUMB, DEPTNAME
FROM ORG
WHERE NOT (DEPTNUMB > 15
AND DIVISION = 'EASTERN')
RESULT:
DEPTNUMB DEPTNAME
10 HEAD OFFICE
15 NEW ENGLAND
42 GREAT LAKES
51 PLAINS
66 PACIFIC
84 MOUNTAIN
Built In Functions
If one built in function is specified in the select clause, all other items in the select list must also be built in functions (unless the group by clause is used)
Null values are not included in any calculation
FINAL TOTALS USING BUILT-IN FUNCTIONS
TASK: Retrieve the maximum salary, maximum commission, total salary
average commission, and total number of distinct salaries for the staff
table
SQL:
SELECT max(salary) Max Salary, max(comm) Max Comm,
sum(salary) Sum Salary, avg(comm) Average Comm,
count(distinct salary) Unique Sal from staff
RESULT:
Max Salary Max Comm Sum Salary Average Comm Unique Sal
------------ --------------- -------------- ---------------------- ------------------
22,959.20 1,386.70 589,192.98 488.07 34
When using Built-in functions and the select clause only has built-in functions declared (see above) then Oracle will return one and only one row. Summary totals bring back only one row.
BUILT-IN FUNCTIONS ExERCISES
1) What is the total number of departments?. See ex51.sql
RESULTS:
(1 ROW SELECTED)
2) How many different divisions are there?See ex52.sql
RESULTS:
(1 ROW SELECTED)
3) List the average salary for managers. See ex53.sql
RESULTS:
(1 ROWS SELECTED)
4) What is the maximum salary for employees with less than 5 years of service? See ex54.sql
RESULTS:
(1 ROWS SELECTED)
5) What is the total years of service for all employees in departments 15, 20, and 42? See ex55.sql
RESULTS
(1 ROW SELECTED)
Group by Clause
 Used in conjunction with built in functions
Conceptually rearranges the table into groups, one group per value of the
group by field
 The result consists of one row per value of the group by field
 Each item in the select clause must be single valued per group
Group by Clause
TASK: Display the minimum, average, and maximum salary for each
job function
SQL:
SELECT JOB, MIN(SALARY), AVG(SALARY),
MAX(SALARY)FROM STAFF
GROUP BY JOB
RESULT:
NOTES:
If used, group by clause must be after the from and where clauses, and before the order by clause
The Having Clause
How do I filter rows from a previous results table?
 Always used with the group by clause
 Just as the where clause eliminates rows from single select query, the having clause eliminates whole groups specified in the group by clause
TASK: For any departments with more than 4 employees, show the total number
of employees in those departments.
EXAMPLE:
SELECT DEPT, COUNT (*)
FROM STAFF
GROUP BY DEPT
HAVING COUNT(*)>4
ORDER BY DEPT
RESULT:
All departments with no more than 4 employees are eliminated from the result
THE HAVING CLAUSE EXERCISES:
1) For each department whose average salary is greater than $18,000, List the
department number, average years of service, and average salary. See
ex61.sql
RESULTS:
(1 ROW SELECTED)
2) List each department number where all employees have at least 5 years of
service. See ex62.sql
RESULTS:
(4 ROWS SELECTED)
3) List each department number having a total commission of at least $1200
See ex63.sql
RESULTS:
(6 ROWS SELECTED)
Retrieval involving Null
1 + NULL = NULL
 RDBMS's supports the concept of a field having null status
 To test a field for null status, a special conditional form is used:
COLUMN-NAME IS {NOT} NULL
EXAMPLE:
INCORRECT:
SELECT ID, NAME
FROM STAFF
WHERE COMM=NULL
CORRECT:
SELECT ID, NAME
FROM STAFF
WHERE COMM IS NULL
Treatment of Nulls
A null value means that there is no value assigned. In other words the value is unknown.
1. What teams have won more games than the Orioles?
2. Are the Orioles tied with the Alley Cats?
3. Are the panthers tied with the Orioles?
4. What is the total wins for the league?
5. What is the average wins per team?
Treatment of Nulls
Whenever a null is used to derive a result, the result is also null (unknown)
Nulls are excluded before Oracle performs any calculations.
Null Values are excluded for:
Comparison
WHERE WINS < 4
WHERE WINS >=4
Computations:
SALARY + COMM * 1.10
Functions involving Null Values
BUILT IN FUNCTIONS
MIN AVG COUNT(DISTINCT)
MAX SUM
TREATMENT OF NULLS
Nulls are always listed last when Order by Clause in ascending sequence is used
Null Values Are Considered In
 Tests for existence of nulls where wins is (not) null
 Count (*) where all rows are considered
 Select distinct clause produces one null value in result
 Unique indexes allow one row to have a null key except primary key index.
 Group by - Creates a separate group for each null
 Order by - Places all nulls at the BOTTOM of the list (ascending order))
TREATMENT OF NULLS
Advantages:
Allows identification of values not yet specified
Allows addition of a new column to an existing table
Allows insertion of a row when not all values are known
Disadvantages
Requires additional processing to handle null decisions
Allows insertion of a row containing incomplete data
LAB 3 - MORE ABOUT SELECTS
Using SQL*PLUS create and execute the following queries using the staff, org and applicant tables. See Lab3.lst for answers.
1. Give all information about each clerk
2. List the name, salary and commission of each employee by department
3. List the names and job functions of all employees working in departments 20,
42, 51, and 84.
4. Give the average salary for each department.
5. List all sales personnel by descending total earnings (Salary Commission).
6. List the names of all employees whose name contains the characters 'ON'.
7. Display all employees whose weekly salary is greater than $300.00.
8. Display all employees whose commission is at least 5% of total earnings.
9. List id, name, salary, and commission for all employees except departments
38 and 41. Order by Department
10. List every department with at least one employee with a null commission.
List a department number only one time.
ADVANCED STRUCTURED QUERY LANGUAGE - Chapter 3
TOPIC OBJECTIVES
This section introduces the more complex SQL statements as used in ORACLE.
When you finish this section, you will be able to:
Create queries called joins which use more than one table
Comprehend when and how to use subquery statements
Identify and use the Union, Intersect and Difference commands
Write SQL Select statements to not only retrieve rows but to insert, delete and update row columns
Advanced DML Functions
Joins
A join allows the selection of columns from one or more tables based upon comparing two or more columns.
For example, the following figure shows a DEPT table with DEPTNO as a primary key and an EMP table with EMPNO as primary key and DEPTNO as foreign key.
DEPT TABLE EMP TABLE
Deptno Dname Empno Mgr Deptno Sal Job
001 SALES 10 40 001 50000 Sales
002 MANUF 20 30 002 35800 Tech
30 .. 002 43000 Mgr.
40 .. 001 70500 Mgr.
50 .. 003 34000 Tech
Join Examples
A query in which data is retrieved from more than one table. Specifically, select empno, ename, mgr and dname from the appropriate dept and emp tables
SQL:
SELECT EMPNO, ENAME, MGR, DNAME FROM DEPT,EMP WHERE
DEPT.DEPTNO = EMP.DEPTNO ORDER BY EMPNO
RESULT:
EMPNO ENAME MGR DNAME
7782 CLARK 7839 ACCOUNTING
7839 KING ACCOUNTING
7934 MILLER 7782 ACCOUNTING
7369 SMITH 7982 RESEARCH
7876 ADAMS 7788 RESEARCH
7902 FORD 7566 RESEARCH
7788 SCOTT 7566 RESEARCH
7566 JONES 7839 RESEARCH
.... ..... ..... ......
Notes about Joins
DEPT  EMP
In the previous example, DEPT.DEPTNO = EMP.DEPTNO is referred to as the JOIN condition
The two fields in the join condition:
 Must be either both numeric or both character
 Should be the same data type (eliminates conversion overhead)
 May have the same or different column names
 May be compared with equal (=), or with inequalities
Should be used with care.
 They can be quite demanding of the system
 One of the most powerful features of relational systems
Qualified names
 When the columns in the tables to be joined are the same name, you must
fully qualify the columns being joined or you will have an ambiguous
reference.
 Suppose the following query is needed
List all department managers and their salary
SQL:
SELECT EMP.DEPTNO,ENAME,JOB,SAL,DNAME
FROM DEPT,EMP
WHERE DEPT.DEPTNO = EMP.DEPTNO AND JOB =`MANAGER';
NOTES: Remember that different tables can contain columns with the same name
Correlation Variables
STAFF Table APPLICANT Table
ID NAME DEPT ..... ID NAME AGE .....
Correlation variables are aliases for table names. They are primarily used when columns in different tables have the same name. This occurs frequently with primary/foreign key relationships established for referential integrity.
SELECT A.NAME, S.NAME FROM APPLICANT A, STAFF S
WHERE TEMPID=ID
A and "S" are referred to as correlation variables
Also referred to as aliases
Advanced DML Functions
Equi-join or INNER-JOIN
An equi-join is a join where a row in one table has a matching row (based upon equal values) in another table based on one (or more)column(s) in each table.
For example, if you needed to select the employee id, name, salary, and department name from the appropriate tables for employees employed by division manager 160, you would:
SELECT dept, id, salary, deptname
FROM STAFF,ORG
WHERE dept= deptnumb and manager = 160
order by dept;
The results are shown in the following figure.
results Table
Dept Id salary Deptname
10 160 22959.2 HEAD OFFICE
10 210 20020 HEAD OFFICE
10 260 21234 HEAD OFFICE
10 240 19260.3 HEAD OFFICE
Advanced DML Functions
Non-equi-join
A non-equi-join uses operators other than the equal to (=) such as less than ( < ) and greater than ( > ). A non-equi-join is a join where a row in one table has a matching row (based upon unequal values) in another table based on one (or more) column(s) in each table.
Example: Find a specific employee whose salary is greater than their
managers salary: Make sure you match manager 50 with employee 170 and the department is 15.
SELECT M.DEPT,S.ID, S.NAME,S.SALARY, M.NAME, M.SALARY FROM
STAFF M, STAFF S WHERE M.JOB = 'MGR' AND M.ID = 50, AND
S.ID=170 AND S.SALARY > M.SALARY
Results:
DEPT ID NAME SALARY NAME SALARY
15 170 KERMISCH 12258.50 HANES 20659.80
(SO NO ROWS WILL BE DISPLAYED BACK BECAUSE THE EMPLOYEE HAS A
SMALLER SALARY THAN THE MANAGER)
As a general rule, non-equi-joins are performed on one row from each table
only)
.
Advanced DML Functions
Outer Join
An outer join may be used to include rows from one table that do not have a matching row in another table.
Example: To find employees with no DEPTNO in the DEPT table use
this outer join:
SELECT DEPT,ID,DEPTNUMB
FROM STAFF,ORG
WHERE DEPT = DEPTNUMB(+).
The resulting table is:
DEPT ID DEPTNUMB
(All matching rows and a employee with a null department value)
NULL 80 NULL
Notice that the plus sign in parentheses (+) tells SQL this is an outer join. Put the (+) on the column on the side of the join where you expect the null value to exist.
More about Aliases
Aliases are very important in some advanced manipulation features like correlated subqueries.
Sometimes, it is important to have two references to the same table so that the table can be joined to itself. These aliases are called correlation variables in this case.
Task: Find all employees in each dept who have less years of experience than
their manager.
SELECT S.NAME, S.DEPT,S.YEARS, M.NAME, M.DEPT, M.YEARS FROM STAFF S, STAFF M WHERE S.DEPT=M.DEPT AND M.JOB = `MGR' AND S.YEARS < M.YEARS
STAFF S STAFF M
NAME DEPT YEARS NAME DEPT YEARS
SANDERS 20 7 SANDERS 20 7
PERNAL 20 8 MARENGHI 38 5
HANES 15 10 HANES 15 10
ROTHMAN 15 7
NGAN 15 5
KERNISCH 15 10
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
RESULT:
KOONITZ 42 6 PLOTZ 42 7
YAMAGUCHI 42 6 PLOTZ 42 7 . . . . . . .
. . . . . . .
Join Exercises:
1. List the department numbers and department names with their appropriate
division manager's name and his/her salary. See EX71.sql
RESULTS:
(8 ROWS RETURNED)
2. For each manager, create a list of people in his/her department whose
salary is greater than the manager's salary. See EX72.sql
RESULTS:
(10 ROWS RETURNED)
3. For each applicant list any staff members with the same name. See EX73.sql
RESULTS:
(NO ROWS RETURNED)
Subqueries
A subquery is a select-from-where expression nested within another select
SELECT TEMPID, NAME FROM APPLICANT
WHERE NAME IN
(SELECT NAME FROM STAFF
WHERE JOB='MGR')
The subquery produces a value or group of values which complete the main query
- More than one level of subquery nesting can be used
- If a subquery produces no results (rows), you get an empty report
Single Valued Subqueries
Provides an alternative for the need to use built in functions in the where
clause..
TASK: Get the names of all applicants evaluated at the
highest education level
SQL:
SELECT NAME FROM APPLICANT
WHERE EDLEVEL =
(SELECT MAX(EDLEVEL)
FROM APPLICANT)
RESULTS:
GASPARD
JACOBS
NOTE: If "=" (Or an inequality) precedes the subquery it must be single
valued
Multivalued Subqueries
TASK: List the id and name for each employee in the eastern division
SQL:
SELECT ID, NAME FROM STAFF
WHERE DEPT IN
(SELECT DEPTNUMB FROM ORG
WHERE DIVISION='EASTERN')
ORDER BY ID
RESULTS:
All employees from departments 15, 20, and 38
The Any Parameter
TASK: List any employee whose salary is greater than at least one
department's average salary
SQL:
SELECT NAME FROM STAFF
WHERE SALARY > ANY
(SELECT AVG(SALARY) FROM STAFF
GROUP BY DEPT)
NOTE:
Condition is true if true for at least one value produced by the subquery
The Exists Parameter
TASK: List each department in Org with at least one employee with more
than 8 years of service
SQL:
SELECT DEPTNUMB FROM ORG
WHERE EXISTS
(SELECT * FROM STAFF
WHERE DEPT=DEPTNUMB AND YEARS > 8)
NOTE:
If subquery produces at least one value, the department is included in the result
Exercise 8:
1 List the managers in the Midwest division. See ex81.sql
RESULTS:
NAME DEPT
PLOTZ 42
FRAYE 51
2. List the managers whose departments average salary is greater than
the overall average salary. See ex82.sql
RESULTS:
DEPT NAME SALARY JOB
10 MOLINARE 22059.2 MGR
10 LU 20010 MGR
10 DANIELS 19260.3 MGR
10 JONES 21234 MGR
3. Find the employee with the highest salary. See ex83.sql
RESULTS:
NAME SALARY
MOLINARE 22959.2
4. Retrieve the employee number, name, salary, and commission of all
employees who earn more than $20,000.00 only if any employee earns less
than $350.00 commission. (Hint: use an exist statement). See ex84.sql
RESULTS: 7 rows
SET OPERATORS (Conjunctions)
Set operators combine the results of multiple queries into a single result. The following table lists SQL set operators in order of precedence from high to low.
Operator Function Example
UNION Combines queries to return all distinct rows ...SELECT ..
returned by any individual query (OR) UNION SELECT ...
INTERSECT Combines queries to return all distinct rows ...SELECT....
returned by every individual query. (AND) INTERSECT SELECT..
MINUS Combines queries to return all distinct rows ....SELECT....
returned by the first query but not the MINUS SELECT.....
second query (AND NOT)
UNION
A UNION conjunction would combine rows in all queries in the union eliminating duplicate rows.
The results would be similar to those returned when using a WHERE clause with an OR logical operator.
TASK: List employees by department. Designate for each employee if his years of service are from 0 to 5, from 6 to 10, or greater than 10
SQL:
SELECT DEPT, ID, NAME, '0-5 YEARS'
FROM STAFF
WHERE YEARS < 6
UNION
SELECT DEPT, ID, NAME ,'6-10 YEARS'
FROM STAFF
WHERE YEARS BETWEEN 6 AND 10
UNION
SELECT DEPT, ID, NAME, 'MORE THAN 10 YEARS'
FROM STAFF
WHERE YEARS >10
ORDER BY 1,2
RESULT:
DEPT ID NAME 0 - 5 YEARS
10 160 MOLINARE 6 - 10 YEARS
10 210 LU 6 - 10 YEARS
10 240 DANIELS 0 - 5 YEARS
10 260 JONES MORE THAN 10 YRS
.. .. .. ..
Exercise 9 on Union:
List all the applicants and staff members, order by ID. Label each person as either "STAFF" or "APPLICANT. See EX91.sql
RESULTS:
44 or 45 rows selected
Provide an employee list which indicates which employees make less than the average and which employees have salaries greater than or equal to the average. See EX92.sql
RESULTS:
35 rows selected
SET OPERATOR INTERSECT
The INTERSECT clause results would be similar to those returned when using a WHERE clause with an AND logical operator.
The following example would produce an empty results table because an employee is only assigned one DEPTNO at any given time
SELECT EMPNO, DEPTNO FROM EMP WHERE DEPTNO = 001
INTERSECT
SELECT EMPNO, DEPTNO FROM EMP WHERE DEPTNO = 003
The following use of intersect would give a non-empty results table:
SELECT EMPNO FROM EMP
INTERSECT
SELECT EMPNO FROM PROJECTB
Results: EMPNO
10
20
The Minus Conjunction
The minus conjunction is similar to using the 'AND NOT' logical operator is a WHERE clause of a SELECT statement
SELECT EMPNO, SAL FROM EMP
WHERE SAL > 46000
MINUS
SELECT EMPNO, SAL FROM EMP
WHERE DEPTNO = 001
Results: EMPNO SAL
50 90000
SELECT EMPNO CONTRACTOR FROM PROJECTB
MINUS
SELECT EMPNO FROM EMP
Results: CONTRACTOR
578
789
MODIFY Functions
SQL Insert a Row:
INSERT INTO ORG
VALUES (95, 'COASTAL', 150, 'MIDWEST','HOUSTON')
RESULT:
Adds the following row to the ORG Table
DEPTNUMB DEPTNAME MANAGER DIVISION LOCATION
95 COASTAL 150 MIDWEST HOUSTON
Data value list must correspond to the list of columns in the table
Null values may be specified for a column with null
MODIFY Functions
SQL Insert Selected Columns
INSERT INTO ORG(DEPTNUMB, DEPTNAME, LOCATION)
VALUES (95,'COASTAL', 'HOUSTON')
 Columns not specified are given the value null
 A value must be specified for any column defined as not null in the table create statement
INSERT INTO MYSTAFF (ID, NAME, DEPT)
SELECT ID, NAME,DEPT
FROM STAFF WHERE JOB = 'CLERK'
Copies all clerk rows from STAFF to table MYSTAFF
The insert (as with all updates) may be performed on a table if
 You created the table
 You have been granted insert authority on the table
Update a single row
Task: Update employee number 150 to change job description to Manager,
Department to 95 and provide a 15% increase in salary.
SQL:
UPDATE STAFF
SET JOB='MGR', DEPT=95, SALARY=SALARY * 1.15
WHERE ID=150
This example updates the department, job and salary for ID 150
Update multiple rows
SQL:
UPDATE STAFF
SET COMM = COMM + 500
WHERE DEPT = 38
This query gives every employee in Department 38 a $500 commission bonus
COMPLEX UPDATE
Task: Provide all employee who worked for Project number 50 a bonus
equal to 15% of their salary. This requires that you search the
Project table to find all employees in Project 50 and then update the
employees Bonus field in the Staff table
Update Staff
Set Bonus = salary * .15
where id in
(Select empno
from project
where projectno = 50);
Result: All employees attached to Project number 50 are given a
15% bonus.
SQL DELETE
Single row delete
1. DELETE FROM STAFF
WHERE ID = 150
Multiple row delete
2. DELETE FROM STAFF
WHERE JOB = 'CLERK'
COMPLEX DELETE
Task: Delete all employee who worked for Project number 50.
Delete from Staff
where id in
(Select empno
from project
where projectno = 50);
Result: All employees attached to Project number 50 are deleted
LAB 4 - SELECTING ROWS FROM MORE THAN ONE TABLE
TASK: Retrieve all employees in department 20. Print out the department name along with their id, name, and salary.
TASK: Select the employee number, name, job, salary, department and division for all employees whose salary is in the range of 15000 to 30000 dollars. Sort the data by division and job. See salrang.sql
RESULTS:
23 rows are selected
3. TASK: Display the rows in staff table that do not have a match in the org
table (an employee who does not have a department number in the org
table) as well as those employees with department numbers that do have a
match in the org table. See outrjoin.sql. Optional - See if you can just return
a staff row(s) that does not have a match in the org table.
RESULTS:
You will have 35 rows returned which include an employee named
JAMES who is a clerk with no valid department number.
LAB 4 - SELECTING ROWS FROM MORE THAN ONE TABLE
4. a. Insert your name and relevant information into the applicant table.
b. Insert a row into the org table which creates a new Division (Southwest),
department number (77), department name (Dallas), location (Plano), and
manager (10).
c. You have been hired by the company. Move your applicant information
from the applicant table to the staff table. Your salary is $50,000.00, you
have no commission, and your job status is MGR. see cmplxins.sql
5. Display all location or division or department names eliminating duplicates.
The company is looking at defining a new set of specifications on the names
it uses so it needs to look at all the current alphanumeric names being used.
Eliminate duplicates. See union.sql
6. You have received a promotion. Upgrade your salary by 10%. Give yourself a
$5,000.00 commission as well. See update6.sql
7. Find the person(s) who has worked with the company longest and give them
a 10% salary increase. See update7.sql
LAB 4 - SELECTING ROWS FROM MORE THAN ONE TABLE
8. Whoops!!. Our applicant tables need to be cleaned up. Delete anyone in
the applicant tables who is now a permanent employee. Please delete
them from the appropriate tables. See cmplxdel.sql
STRUCTURED QUERY LANGUAGE EXTENSIONS - Chapter 4
TOPIC OBJECTIVES
This section introduces the NON-ANSI standard SQL statements as used in ORACLE.
When you finish this section, you will be able to:
· Understand how to expand a column headings width
for display purposes
· Create queries which prompt users for input data to a
query
· Utilize non standard built in functions such as
INITCAP and INSTR
· Produce edited numeric columns
· Understand what smart dates are and how to use them in calculations
ORACLE SQL Plus Commands
FORMATS
 Oracle provides capabilities to change the width and format of datatypes:
 Column width
 Numeric
 Character
 Date
 CHANGING THE COLUMN WIDTH
DALLAS Mayor DALLAS Mayor
'COLUMN colname FORMAT An' with 'n' being
the desired column width.
COLUMN NAME FORMAT A13
SELECT DEPT, NAME FROM STAFF
The only thing that may vary in a character column is the column width.
NUMBER FORMATS
SET NUMFORMAT $99,999.99
select id,name,salary,comm
from staff where id = 10
RESULT:
ID NAME SALARY COMM
10 SANDERS $18,357.50 -
To reset NUMFORMAT back to the original settings:
SET NUMFORMAT NUMBER FORMATS
The following formats can be used for numeric data
INITIAL
FORMAT DATA RESULT
999.99 56.478 56.48 Rounds to 2 decimal places
9,999 8410 8,410 Comma separates thousands
09999 607 00607 Leading zeros fill format
9999 -5609 -5609 Minus sign normally precedes
9999MI -5609 5609- Minus sign follows number
9999PR -5609 <5609> Negative number in parenthesis
B999 0 Blank when zero
99.99 124.98 ##.## Value too large for format
$99.99 45.23 $45.23 Dollar sign displayed
$99.99PR -45.23 <$45.23> Combined formats
9.99EEEE 1200 1.20E+03 Exponential notation
· You can set the numeric format for individual columns by using the following command.
column salary format $99,999.99
select name,salary,comm from staff
where id = 10;
RESULT:
NAME SALARY COMM
PERNAL $18,171.25 612.45
CHARACTER
Functions are used to modify character columns. The character
functions are listed below.
 INITCAP(char) capitalizes the first character of the specified string.
Example : SELECT ENAME,INITCAP(ENAME) FROM EMP;
 INSTR(char1,char2,n,m) returns the position of the Mth
occurrence of char2 in char1 beginning at position n.
 Example : Find the employees that have the string 'AM'
beginning in position 2 of the ENAME column.
SELECT ENAME FROM EMP WHERE INSTR(ENAME,'AM')=2;
 LENGTH(char) - Returns the length of a string.
 Example : Find the length of all of the ENAME occurrences.
SELECT ENAME, LENGTH(ENAME) FROM EMP;
 RTRIM or LTRIM(char) - RTRIM trims trailing spaces from a string.
· Example : Using the Length function a Rrim, find the actual number of characters each name takes in the ENAME column by eliminating trailing spaces from all of the ENAME occurrences.
SELECT ENAME, LENGTH(RTRIM(ENAME)) FROM EMP;
 SUBSTR(char,n,m) - A substring of char beginning at position
n positions m long.
 Example : Find the third character in the ENAME
column for all employees in the EMP table.
SELECT SUBSTR(ENAME,3, 1) FROM EMP;
 LOWER or UPPER(char) - Changes uppercase characters to lowercase.
DATE FORMATS
SELECT TO_CHAR(MDATE,'MM-DD-YYYY') NEWDATE FROM ORDERS
RESULT:
NEWDATE
02-08-1998
YYYY or YYY or YY or Y Produces 1998 or 998 or 98 or 8.
BC or AD BC/AD indicator.
Q Quarter of year. 1st or 2nd or 3rd or 4th.
MM Month.
MONTH Name of Month, padded with blanks to length of 9.
SELECT EMPNO ID,ENAME,TO_CHAR(HIREDATE,'MONTH DD,YYYY')
HIREDATE FROM EMP WHERE empno = 7900
RESULT:
ID NAME HIREDATE
7900 JAMES FEBRUARY 08, 1998
FMMONTH Name of Month variable length.
MON Name of Month as 3-letter abbreviation.
SELECT EMPNO ID,ENAME,TO_CHAR(HIREDATE,'MON DD,YYYY')
HIREDATE FROM EMP WHERE empno = 7900
RESULT:
ID NAME HIREDATE
7900 JAMES FEB. 08, 1998
WW or W Week of Year or Month
DDD or DD or D Day of Year, Month or Week.
DAY Name of Day, padded with blanks
to a length of 9.
FMDAY Name of day variable length.
DY Name of Day, 3-letter abbreviation (Mon,Tue,etc.)
SELECT EMPNO ID,ENAME,TO_CHAR(HIREDATE,'MON DD,DY,YYYY')
HIREDATE FROM EMP WHERE EMPNO = 7900
RESULT:
ID NAME HIREDATE
7900 JAMES FEB. 08, WED, 1998
J Julian day; number of days since
12/31/4713 B.C.
AM or PM Meridian indicator.
HH or HH12 Hour of day in 12 hour format.
HH24 Military clock time
/., Punctuation is printed as desired in
format.
SELECT EMPNO ID,ENAME,TO_CHAR(HIREDATE,'MM/DD/YY')
HIREDATE FROM EMP WHERE EMPNO = 7900
ID NAME HIREDATE
7900 JAMES 02/12/98
anything Quoted string is printed in format.
codeTH Suffix to make ordinal number (e.g.
DDTH for 4TH).
 Note that capitalization in spelled-out word or abbreviation
follows format elements :
SELECT EMPNO,ENAME,
TO_CHAR(HIREDATE,'DDth of Month,YYYY') FROM EMP
would yield 8th of February, 1998 for example.
The DATE FUNCTIONS
Allow for great flexibility in using dates. Some of the
functions refer to date and others to date and time.
 ADD_MONTHS(d,n) - Date 'd' plus 'n' months.
SELECT EMPNO, ADD_MONTHS(Hiredate, 6)
FROM EMP
RESULT:
· LAST_DAY(d) - Returns the last day of the month specified.
SELECT EMPNO, LAST_DAY (Hiredate)
FROM EMP
RESULT:
· TRUNC(d) - Truncates the time in a date field
SELECT EMPNO, HIREDATE
FROM EMP
WHERE TRUNC(HIREDATE) =
TRUNC(SYSDATE);
RESULT:
SYNTAX OPERATORS & PARAMETER SUBSTITUTION
The SYNTAX operators are special characters used to define
queries to Oracle.
'&n' Ampersand operator allows parameter
substitution
.
'&var-name' Substitution of value of variable. When variable is
undefined, then SQL*PLUS prompts for value each
execution.
'&&var-name' Similar to '&var-name' except prompts
only the first time in an execution for 'var-name'.
Parenthesis ( ) Surround a subquery or function.
select substr(name,1,instr(name,' `)) FIRSTNAME from name;
Single quote ' Surrounds a character or date constant.
Use two single quotes to represent one single quote.
Double quotes (") Surrounds a column name or alias that
contains special characters(such as
spaces) or literal data in a date format.
At (@) sign Used to define tables linked from a
remote site through SQL*NET. For example
SELECT * FROM EMP@BOSTON.
THE CONVERSION FUNCTIONS
The data conversion functions are used to change values from one format to another. A conversion may need to be done where inconsistent data types are not allowed, such as in arithmetic functions. These functions may also be used to convert between
generic SQL formats and SQL*PLUS formats.
Descriptions of the conversion functions follow.
 TO_CHAR(n[,fmt]) converts number 'n' to a CHAR value in the
format specified.
SELECT EMPNO,ENAME,TO_CHAR(YEARS) FROM EMP;
When 'fmt' is omitted, 'n' is converted to a CHAR value
exactly long enough to hold the significant digits.
 TO_CHAR(d[,fmt]) converts date 'd' to a CHAR value in the
format specified.
SELECT EMPNO,ENAME,TO_CHAR(HIREDATE,'MM-DD-YY')
FROM EMP;
 TO_DATE(char[,fmt]) converts a date from a CHAR value of
format 'fmt' to a date value.
SELECT EMPNO,ENAME,TO_DATE(`FEB, 08,1995',MMDDYY)
FROM EMP;
TO_NUMBER(char) converts a CHAR value containing a number to a NUMBER value.
SELECT ID,NAME,TO_NUMBER(SSN#) FROM EMP;
OTHER FUNCTIONS
DECODE(char,val,code,val,code,...default) translates coded column values into the meanings of the code.
SELECT EMPNO,E NAME, DECODE(CODE,1,'ADD',2,'DELETE',3,'UPDATE','ERROR')
FROM EMP;
Using DECODE to order rows in a non-standard order.
SELECT CODE,EMPNO,ENAME FROM EMP
ORDER BY DECODE(CODE,2,-3,3,-2,CODE);
NVL(x,expr) displays 'expression' if 'x' is null else 'x' is displayed.
SELECT EMPNO,ENAME,NVL(TO_CHAR(COMM),'NO VALUE')
FROM EMP;
selecting today's date
select empno,ename,sysdate from emp;
LAB 5 - Using SQL*PLUS commands for reporting
(See LAB5.LST for answers)
1. Display the employee number, name and salary of all managers who
are in department 10. Format salary so that it has a dollar sign.
2. Select all division managers from the org table. Change the department
heading to DEPARTMENT.
3. Set the numeric format for all columns in the staff table to equal
$999,999.99PR.
4. Display all employees information who have a commission greater than a
user defined value. Use a temporary variable to prompt the user for the
commission value.
5. Retrieve all information about employees who have more than 5 years of
service. Display todays date along with their column information. Produce
the same report but show todays date as 6 months from today.
6. Display all information about employees who are in SALES. If they have a
null commission, print out NO COMM in place of the NULL value.
DATA DEFINITION LANGUAGE - Chapter 5
TOPIC OBJECTIVES
This section introduces the Data Definition Language (DDL) component of SQL.
When you finish this section, you will be able to:
 Use Data Definition Language (DDL) to create:
· tables
· synonyms
· indexes
 Remove objects using the Drop statement
 Alter table objects and modify data attributes
 Base Tables
DDL Commands
CREATE TABLE
INDEX
VIEW
SYNONYM
ALTER TABLE
DROP TABLE
INDEX
VIEW
SYNONYM
LOGICAL DEFINITION - TABLES
· Creating a Table
- Composed of:
·Table Name - Must be unique for each userid
·Column Name(s) - Must be unique within a table
·Column Datatype
·Column must indicate whether it allows Nulls or Not
Null
EXAMPLE:
CREATE TABLE org
(deptno number(4) NOT NULL,
deptname char(9) NULL,
manager number(3) NOT NULL,
division char(15) NOT NULL,
location char(20))
CREATE TABLE MYSTAFF
(ID NUMBER (7) NOT NULL PRIMARY KEY,
NAME CHAR (9) DEFAULT `JOHN DOE',
DEPT NUMBER(3) DEFAULT 10,
JOB CHAR(5),
YEARS DATE,
SALARY NUMBER (7,2),
COMM NUMBER (6,2) )
For each column, specify:
 Column name
 The data type
 Maximum length for char, varchar, and number
 number of decimal places, (if data type) is number and decimals required
 Comma to separate from the next column description, if present
 Default keyword allows for a default value to be inserted if no value provided on an insert into the table.
 PRIMARY KEY establishes this column as NOT NULL automatically and creates a unique index on this column.
NOTE: NOT NULL will prohibit the entry of null value for the designated column
LOGICAL DEFINITION - SYSTEM DATATYPES
Datatypes for Tables
· System-supplied Datatypes
- 12 datatypes provided by ORACLE
·Character (char, nchar,varchar,nvarchar2,varchar2,long)
·Binary (raw,longraw,blob)
·Number (number(n,d))
·Date (date)
·Other (rowid,)
· User-Defined Datatypes
·Datatypes built by the user
·Defined in terms of system-supplied datatypes
Column Data Types
For character data
CHAR(N) - Use if all column values are the same length or use if column values are variable length but never more than 255 bytes
VARCHAR2 - Variable length columns up to 2000 characters.
Nchar & nvarchar2 - fixed or variable length used for large character sets
For numeric data
NUMBER(n) - By default up to 38 digits
NUMBER(n, m) - Can specify fixed number of decimal places. May have up
to 105 significant digits
For scalar data
DATE/TIME - 7 byte field which can be converted to numeric or character
The default date format for input, output, and comparison is:
DD-MON-YY OR 30-DEC-96
Valid dates must be between
January 1, 4712 BC
December 31, 4712 AD
USER DEFINED DATATYPES
Adding User-Defined Datatypes
· The TYPE statement is used to assign an ORACLE datatype
to a variable or a whole class of variables.
ORACLE> create type address_type (
street varchar2(40),
city varchar2(30),
state varchar2(2),
zip_code number(5));
ORACLE> table created
CREATE TYPE EMPLOYEE_TYPE (
name varchar2(30),
hire_date date,
address address_type,
member procedure give_raise);
These Oracle8 datatypes are created as part of the capabilities to help you
standardize code and applications. The use of encapsulation principles allows
you through defaults, check constraints, stored procedure & functions and user
defined datatypes to place code with the actual data..
CREATING TABLE AND COLUMN CONSTRAINTS
Oracle provides for table and column constraints called PRIMARY
KEY, FOREIGN KEY, UNIQUE, CHECK and NOT NULL. The following
list provides a comparison of these constraints with other
implementations.
Constraints Other Implementation
NOT NULL Alter table
CHECK (Table Level) Create TRIGGER or PL/SQL
CHECK (column level) PRO* Language
UNIQUE Create UNIQUE NONCLUSTERED index
Primary Key Create UNIQUE (CLUSTERED) index
Foreign Key/Reference Create TRIGGER or PL/SQL
CREATING DEFAULT CONSTRAINTS
TASK: Create a DEFAULT for the commission column in the STAFF
table. The Default value is $50.00.
SQL:
Alter table STAFF
modify comm DEFAULT 50.00;
RESULT: The DEFAULT is established for the column comm
in the STAFF table.
NOTES:
1. Can be created at the column and/or table level
2. Are automatically bound to the column in which it is defined, not to the datatype
CREATING CHECK CONSTRAINTS
TASK: Create a CHECK CONSTRAINT called loc_check1 which
specifies the department locations for the loc column in the dept
table
SQL:
ALTER TABLE dept
ADD
CONSTRAINT loc_check1
CHECK (loc IN (`DALLAS', `HOUSTON', `LITTLE ROCK'));
RESULT: The column loc must now conform to the CHECK
CONSTRAINT loc_check1
SQL:
ALTER TABLE DEPT
DROP CONSTRAINT loc_check1
RESULT: Erases the CONSTRAINT from the database catalog.
NOTES:
1. Can only be dropped by the owner
2. Cannot contain subqueries
CREATING UNIQUE CONSTRAINTS
TASK: Create an index on the department name column (deptname)
in the org table using the UNIQUE constraint called
unq_dname to ensure that no department has a duplicate
name
SQL:
ALTER TABLE ORG
ADD CONSTRAINT UNQ_DNAME
UNIQUE (DEPTNAME)
RESULT: The column name cannot have two rows with the same
index value. This UNIQUE command creates a unique
index which prevents redundant index values from
occurring.
SQL: ALTER TABLE ORG
DROP CONSTRAINT unq_dname
RESULT: Erases the CONSTRAINT from the database catalog.
NOTES:
1. ARE enforced through the creation of a UNIQUE clustered or nonclustered index
on the specified column(s)
2. Multiple UNIQUE constraints can be placed on a table
3. The default is for a nonclustered index to be created unless an index type is
specified.
4. If an INSERT or UPDATE violates the UNIQUE requirement of this index, a
constraint violation message is received rather than a general index insert error
message.
CREATING REFERENTIAL INTEGRITY CONSTRAINTS
TASK: Create the PRIMARY KEY CONSTRAINT for the ORG table
called PK_ORG_DEPT. The Index that is created should be a
unique index.
SQL:
CREATE TABLE ORG
(DEPTNUMB NUMBER(2)
CONSTRAINT pk_org_dept PRIMARY KEY,
DEPTNAME CHAR(14),
MANAGER NUMBER(4),
DIVISION CHAR(9),
LOCATION CHAR(15))
RESULT: The column deptnumb uniquely identifies a row and the
PRIMARY KEY CONSTRAINT automatically creates a
UNIQUE index for that column preventing duplicate key
values.
SQL: ALTER TABLE ORG
DROP CONSTRAINT pk_org_dept
RESULT: Erases the CONSTRAINT from the database catalog.
NOTES:
1. Can specify CLUSTERED or HASH indexes
2 Column must be NOT NULL
3. Only one PRIMARY KEY declaration per table but it may contain multiple
columns.
4. Can only add a primary key to an existing column if the table does not have
have any rows.
CREATING REFERENTIAL INTEGRITY CONSTRAINTS
TASK: Create the FOREIGN KEY CONSTRAINT for the STAFF table
called FK_STAFF_DEPT.
SQL:
ALTER TABLE STAFF
ADD
CONSTRAINT fk_staff_dept
FOREIGN KEY (dept)
REFERENCES org
RESULT: The column dept identifies the row for the FOREIGN
KEY CONSTRAINT. The FOREIGN KEY reference allows
multiple occurrences of the key in the foreign key table.
The REFERENCES Constraint only references tables in the
same databases. The PRIMARY KEY must already exist or
a UNIQUE constraint (Secondary relationships) must be
established. The FOREIGN KEY option does not create an
index
SQL:
DROP CONSTRAINT fk_staff_dept
RESULT: Erases the CONSTRAINT from the database catalog.
NOTES:
1. Primary and Foreign Key domains must match in type and number of columns
2. You may also disable or enable any constraints defined via:
ALTER TABLE STAFF
DISABLE CONSTRAINT FK_STAFF_DEPT
OR
ALTER TABLE STAFF
ENABLE CONSTRAINT FK_STAFF-DEPT
INDEXES
NON-UNIQUE INDEXES
TASK: Create an Index so that ORACLE can retrieve data
based upon an Index search versus a table scan
SQL:
CREATE INDEX xname
ON STAFF (name)
RESULT: Index xname is built with the key field of NAME.
The Data Dictionary Views which provide the user with index information are:
· USER_INDEXES
· DBA_INDEXES
· ALL_INDEXES
· USER_IND_COLUMNS
NOTES:
 A general guideline is to create an index on anything you want to search frequently.
 Primary keys should always be indexed uniquely.
 Foreign keys should also be indexed, to help you find the information they point to more efficiently.
 In the case of joins , the system can perform the join much faster if the columns are sorted.
 Must be the table owner in order to create or have Index privilege on table .
UNIQUE INDEXES
TASK: Create a unique index on the primary key field
DEPTNUMB of the ORG table
SQL:
CREATE UNIQUE INDEX XORG
ON ORG (DEPTNUMB)
RESULT: Index XORG is created which will not allow duplicate
Department numbers in the ORG table.
To allocate more space to an index when high activity is expected:
ALTER INDEX XORG
ALLOCATE EXTENT (SIZE 20M
DATAFILE `C:\ORANT\NEWXORG.DBF');
To deallocate space not used above the high water mark:
ALTER INDEX XORG
DEALLOCATE UNUSED;
NOTES:
1. Enforces uniqueness of Rows
2. Speeds Joins (Referential checks)
3. Speeds Data Retrieval
4. Speeds ORDER BY and GROUP BY
COMPOSITe INDEXES
TASK: Create an index on name and department on the
STAFF table
SQL:
CREATE INDEX xstaff_dept
ON STAFF (NAME,DEPT)
RESULT: Index xstaff_dept is created which will allow
duplicate name and dept columns in the STAFF table.
NOTES:
 A composite index specifies two or more columns as the index
 Composite columns are searched as a unit
 Column order in the CREATE INDEX statement doesn't have to match column order in the CREATE TABLE statement
 May create either a unique, non-unique or even a clustered index using a composite index.
 Allow certain queries to be satisfied by examining only the index
blocks for those columns making up the concatenated index
 Sometimes allow two columns with low selectivity to be combined
to form a concatenated index with high selectivity
 May be used by a query when the query utilizes the leading
portions of the concatenated index.
 May not be used by a query when the first column(s) of the
concatenated index is (are) not used in the query
· If more than one column is used frequently, place the MOST
SELECTIVE column first. (Can have up to 16 columns)
CONCATENATED INDEXES CONTINUED
Create index staff_id on staff (id,name) NOLOGGING
tablespace pers_indx
Indexes are used to satisfy the following queries since they reference the leading edge of the index.
select * from staff where id =50;
select * from staff where name like `V%' and id between 50 and 100;
It is possible to produce a query, which does not even look at the actual base table.
select id,name from staff where name = `SMITH' and id > 300;
(Here the columns selected are all in the actual index data blocks)
The index is NOT used if id does NOT reference the leading column of the index.
select * from staff where name like `V%'
REBUILDING INDEXES
Use the ALTER INDEX command to:
· Move an index to another tablespace
· Improve space utilization by removing deleted entries
· Change a reverse key index to a normal B-tree index and vice versa
ALTER INDEX XORG REBUILD TABLESPACE NEWINDEX;
NOTE: Index rebuilds create the new index by using existing indexes as the data
Source Sorts are not required with the rebuild making them more efficient. The old
Index is deleted after the new index is built. The resulting index does not contain any
Deleted entries.
BITMAP INDEXES
Bitmap Indexes are used for:
· Used for Low-cardinality columns
· Good for multiple predicates
· Use minimal storage space
· Best for read-only systems
· Good for very large tables
CREATING AND MAINTAINING BITMAP INDEXES
CREATE BITMAP INDEX INV_BIKE_COLOR
ON INVENTORY (COLOR)
STORAGE (INITIAL 200K NEXT 200K
PCTINCREASE 0) TABLESPACE ORASERVE;
CREATE_BITMAP_AREA_SIZE defines the amount of memory for an
index creation. The default is 8mb. The higher the cardinality the more
memory you will need.
BITMAP_MERGE_AREA_SIZE defines the amount of memory used
to merge bitmaps retrieved from a range scan of an index. The default
is 1 MB.
In a DSS environment, data is usually maintained by using bulk inserts and
updates. Index maintenance is deferred until the end of each DML operation.
For example, if you insert 1,000 rows into a table that has a bitmapped index,
the bitmapped column information and the ROWID information from the inserted
rows are placed into the reference to the sort buffer, and then the updates of all
1,000 index entries are batched. The SORT_AREA_SIZE parameter will need
to be monitored when using these indexes.
Bitmap indexes should be investigated and tested for Data Warehousing applications, Financials and all low-cardinality accesses to tables where the
predicates are not widely dispersed.
CREATING REVERSE KEY INDEXES
Create unique index po_no_idx on puorder (po_no)
REVERSE pctfree 30
storage (initial 400k next 400k pctincrease 0)
tablespace jerindx.
Creating a reverse key index reverses the bytes of each column key value, keeping the column order in case of a composite key.
Use a Reverse key index when an ever-increasing key will repetitively degrade
the index height level and cause the HOT SPOT syndrome.
INDEX-ORGANIZED TABLES
 Index contains both the primary key and other column values
No duplication of the values for the primary key column (less storage)
Faster key-based access for queries involving exact matches or range
searches or both.
Logical Rowid used instead of a physical ROWID. Access to this value is
through a UROWID.
CREATING INDEX-ORGANIZED TABLES
CREATE TABLE SALES
(OFFICE_ID NUMBER(3) NOT NULL,
QTR_END DATE,
REVENUE NUMBER(11,2),
REVIEW VARCHAR2(200)
CONSTRAINT SALES_PK PRIMARY KEY (OFFICE_ID,QTR_END)
)
ORGANIZATION INDEX TABLESPACE JERINDX
PCTTHRESHOLD 20
INCLUDING REVENUE
OVERFLOW TABLESPACE USER_DATA;
IOT-TABLES store as many rows in a leaf page as PCTTHRESHOLD limit
will allow. The IOT-Table will store the most frequently used columns with
the primary key value. Non key column values that are not used frequently
are kept in the overflow tablespace. This is called the overflow area.
IOT ROW-OVERFLOW STRATEGY
 PCTTHRESHOLD Clause
This clause specifies the percentage of space reserved in the index for an
index organized table row. If a row exceeds the size calculated based upon
this value, all columns after the column named in the INCLUDING clause are
moved to the overflow segment. If OVERFLOW is not specified the rows
exceeding the threshold are rejected. The default PCTTHRESHOLD = 50.
 INCLUDING Clause
This clause specifies a column to be placed into the IOT Table and all other
row columns to be placed in overflow. Oracle accommodates all non-key
columns up to the column specified in the INCLUDING clause in the LEAF
block provided it does not exceed the specified threshold.
 OVERFLOW Clause and Segment
This clause specifies the non-key columns exceeding the specified
THRESHOLD and are subsequently placed in the OVERFLOW segment.
INDEX BEFORE OR AFTER LOADING DATA
Issues to consider when creating indexes and loading data:
 Indexes slow down data loading
· Usually more efficient to index data after loading it
· The sort area may not be large enough for extremely large tables
Consider using the NOSORT option if data has been loaded in ascending key order:
ORACLE> CREATE INDEX BIG_BIGNO ON BIG(BIGNO) NOSORT
TABLESPACE BIG_INDEX
INDEXES
EXERCISES:
1. What are the advantages of using indexes?
2. When would you create a unique index? What does it enforce?
3. What is the difference between a clustered index and nonclustered index?
4. When is a clustered index advantageous?
5. Why would you create a composite index?
Adding a column to an existing TABLE
ALTER TABLE STAFF
ADD AGE NUMBER(3);
Column name AGE is added at the end of the STAFF
Initial value for all rows is null (thus, you cannot specify not null in the alter statement
Columns can also have their datatype lengths modified.
ALTER TABLE STAFF
MODIFY DEPT NUMBER(4);
Synonyms
Create synonym AV8b for Harrier;
Create synonym NC8801 for Harrier;
Create synonym jumpjet for Harrier
A synonym is an alternative name for a table (Base or View)
In the example, the table Harrier can now be referred to as an AV8b for the soldier, or a jumpjet to a designer of aircraft, or as NC8801 for aircraft technician who need to work on a particular craft. Each customer has their own name for the aircraft which is easily identifiable by each.
SELECT * FROM jumpjet
The name jumpjet is completely private and local to the user issuing the create statement
Deleting Catalog Items
DROP TABLE CUSTOMER
DROP VIEW SALSDAT
DROP SYNONYM MYSTAFF
DROP INDEX XSTAFF
When a table is dropped:
 All data in the table is gone
 All associated views and indexes are also dropped
 All table authorizations are dropped
Views
 A view is a virtual table. No data is actually stored for a view
 The data represented by a view is actually stored in one or more base tables
 The view definition (what it contains) is stored in the catalog
Base Table Employee
ID NAME YEARS SALARY
---- ----------------- ------------ --------------
10 SANDERS 7 18357.50
20 PERNAL 8 18171.25
30 MARENGHI 5 17506.75
40 O'BRIEN 6 18006.00
50 HANES 10 20659.80
60 QUIGLEY - 16808.30
70 ROTHMAN 7 16502.83
80 JAMES - 13504.60
90 KOONTZ 6 18001.75
100 PLOTZ 7 18352.80
110 NGAN 5 12508.20
120 NAUGHTON - 12954.75
130 YAMAGUCHI 6 10505.75
140 FRAYE 6 21250.00
150 WILLIAMS 6 19456.50
160 MOLINARE 7 22959.20
170 KERMISCH 4 12258.50
View Table Persemp
ID NAME SALARY
---- ----------------- --------------
10 SANDERS 18357.50
20 PERNAL 18171.25
30 MARENGHI 17506.75
40 O'BRIEN 18006.00
110 NGAN 12508.20
120 NAUGHTON 12954.75
130 YAMAGUCHI 10505.75
140 FRAYE 21250.00
150 WILLIAMS 19456.50
160 MOLINARE 22959.20
170 KERMISCH 12258.50
Create View SQL
CREATE VIEW PERSEMP AS
SELECT ID, NAME, SALARY
FROM EMPLOYEE
WHERE NOT ID BETWEEN 50 AND 100
NOTE:
 The select statement is not actually executed but stored in the catalog as part of the view definition
 Any table that can be obtained via the select statement can also be defined as a view (excluding union and order by)
 View definition may reflect a join
 User may issue queries against a view table just like a base table:
SELECT ID, NAME
FROM PERSEMP
WHERE SALARY >15000
Column Names
CREATE VIEW DEPTSAL (DEPARTMENT, AVGSAL)
AS SELECT DEPT, AVG(SALARY)
FROM STAFF
GROUP BY DEPT
HAVING COUNT (*)>4
QUERY:
SELECT * FROM DEPTSAL
RESULT:
NOTE:
Column names may be specified for the view and must be if any selected column is:
1) A built in function
2) An arithmetic expression or constant
3) Named the same as another column in a table
JOIN views
CREATE VIEW DEPT2
AS SELECT DEPTNUMB, MANAGER, NAME
FROM ORG, STAFF
WHERE MANAGER = ID
QUERY:
SELECT * FROM DEPT2
RESULT:
Views of Views
CREATE VIEW PERSEMP2
AS SELECT NAME, DEPT, SALARY
FROM STAFF
CREATE VIEW DEPTSAL (DEPARTMENT, AVGSAL)
AS SELECT DEPT, AVG(SALARY)
FROM PERSEMP2
GROUP BY DEPT
Note:
A view may even consist of a join between a base table and another view
View Retrieval Queries
View retrieval queries are converted into equivalent operations on the underlying base tables
CREATE VIEW PERSEMP3 (NAME, TOTEARN)
AS SELECT NAME, SALARY + COMM
FROM STAFF
WHERE JOB= 'CLERK'
ACTUAL QUERY:
SELECT * FROM PERSEMP3
WHERE TOTEARN > 18000
CONVERTED TO:
SELECT NAME, SALARY + COMM
FROM STAFF
WHERE JOB = 'CLERK'
AND SALARY + COMM > 18000
NOTE:
Do Not use a view field which represents a built in function in the where clause
Ability to update views
In ORACLE, only row-and-column-subset views can be updated
CREATE VIEW DEPTSAL (DEPT, AVGSAL)
AS SELECT DEPT, AVG(SALARY)
FROM STAFF
GROUP BY DEPT
How would the following update be handled?
UPDATE DEPTSAL
SET AVGSAL = 15000
WHERE DEPT = 38
Update on a View
Row-and-column-subset views may be updated just like a base table. In fact,
the converted SQL actually updates the base table.
CREATE VIEW PERSEMP4 (ID, NAME, SAL)
AS SELECT ID, NAME, SALARY
FROM STAFF
WHERE DEPT = 38
Actual SQL:
UPDATE PERSEMP4
SET SAL = SAL * 1.15
Converted to:
UPDATE STAFF
SET SALARY = SALARY * 1.15
WHERE DEPT = 38
Lab 6 - MORE ABOUT CREATING TABLES AND INDEXES
Create 7 tables in the appropriate tablespace. The seven tables are called: PRESIDENT, ELECTION, ADMIN_PR_VP, ADMINISTRATION, PRES_HOBBY, PRES_MARRIAGE, STATE. See pres.sql. The specs for these tables can be found on subsequent pages of this lab. Remember to check the sample against the specs to make sure they match up..)
Table Specifications:
We want to collect these items of data about presidents of the United States into these tables:
NULLS
ITEM TYPE LENGTH ALLOWED
================================================================
PRESIDENT NAME CHAR 20 NO
YEAR BORN SMALLINT NO
NUMBER YEARS SERVED SMALLINT NO
AGE AT DEATH SMALLINT YES
PARTY CHAR 20 NO
STATE BORN CHAR 20 NO
STATE CHAR 20 NO
YEAR STATE ENTERED U.S. SMALLINT NO
ADMINISTRATION STATE ENTERED SMALLINT YES
ADMINISTRATION NUMBER SMALLINT NO
YEAR INAUGURATED SMALLINT NO
VICE-PRESIDENT NAME CHAR 20 NO
PRESIDENT'S HOBBIES CHAR 20 YES
PRESIDENT'S SPOUSE CHAR 20 YES
YEAR MARRIED SMALLINT YES
PRESIDENT'S AGE AT MARRIAGE SMALLINT YES
SPOUSE'S AGE AT MARRIAGE SMALLINT YES
NUMBER OF CHILDREN SMALLINT YES
ELECTION YEAR SMALLINT NO
CANDIDATE CHAR 20 NO
VOTES SMALLINT NO
WINNER/LOSER INDICATOR CHAR 1 NO
Lab 6 - MORE ABOUT CREATING TABLES AND INDEXES
TABLE COLUMN NAMES AND RELATIONSHIPS
The logical data base design process suggest tables with the following
columns:
PRESIDENT:
pres_name, birth_yr, yrs_serv,death_age,party,state_born
ADMINISTRATION:
admin_nr, pres_name,year_inaugurated
ADMIN_PR_VP:
admin_nr, pres_name, vice_pres_name
STATE:
state, admin_entered,year_entered
PRES_HOBBY:
pres_name,hobby
PRES_MARRIAGE
pres_name,spouse_name,pr_age,sp_age,nr_children,mar_year
ELECTION:
election_year,candidate,votes,winner_loser_indic
Lab 6 - MORE ABOUT CREATING TABLES AND INDEXES
PRESIDENT TABLE QUERIES
Insert your name into the PRESIDENT table. Execute uinsert.SQL to load the tables. No changes are needed to these inserts. See: uinsert.SQL.
Execute 'SELECT' statements to verify the data exists in each of your tables.
List the president's name, year born, year married, and spouse's name of all married presidents.
Show the average votes received by winning candidates.
Join PRESIDENT and PRES_HOBBY on PRES_NAME.
Add data to the ELECTION table for the 1984 election. Ronald Reagan received 525 electoral votes.
Create a single list (without duplicates) of all the names of all individuals mentioned in the lab tables. Present the output in name order. (use a union).
Change all occurrences of 'Republican' to 'Conservative'.
Create a SPOUSE table that contains spouse name and marriage year. Load it from the PRES_Marriage table.
California has fallen into the Pacific. Delete it from the STATE table.
How many candidates have their been?
Lab 6 - MORE ABOUT CREATING TABLES AND INDEXES
12. Add a column to the STATE table for state flower.
13. Create a table for flowers containing columns for flower name and color.
Insert your own state flower data.
14. Add a column for height in the FLOWER table.
15. Delete the FLOWER table
16. Which Presidents never won an election? (Use a subquery)
Optional Queries:
1. Summarize total votes by candidate without regard to election year. Show in
descending total vote sequence.
2. Add yourself as a candidate in the election table, then using a complex
insert, add yourself to the PRESIDENT table as the next president adding
appropriate values as needed using data (your name) from the election table.
PL/SQL PROGRAMMING - Chapter 6
TOPIC OBJECTIVES
This section covers how to use the PL/SQL language. PL\SQL allows for SQL statements to utilize a control-flow procedural language which provides enhanced
SQL manipulation capabilities. When you finish this section, you will be able to:
Recognize how and when to use PL/SQL statements within SQL*PLUS
Understand the structured block constructs
Identify control flow language constructs used by PL/SQL
Write PL/SQL statements to retrieve multiple rows and/or columns from within SQL*PLUS
Understand and define PL/SQL functions and routines
Recognize and use PL/SQL triggers
OVERVIEW OF PL/SQL
The PL/SQL TECHNOLOGY
Extends the standard SQL ANSI code.
Provides a procedural language capability beyond Data Manipulation Language
Brings to ORACLE high-performance capabilities:
- Looping, branching and control flow language
- Structured block processing concepts
- Available across numerous platforms
- Interfaces with other ORACLE products
- integrated with SQL Dictionary
THE PL/SQL BLOCK STRUCTURE
PL/SQL is made up of three parts
DECLARATION (optional)
Contains all variables, constants,
cursors, and user-defined exceptions
EXECUTION
Contains SQL & PL/SQL statements to
manipulate data in the database
EXCEPTION (optional)
Specifies the actions to perform when
errors and/or abnormal conditions arise
END;
NOTE:
PL/SQL Blocks begin with the DECLARE statement and end with the END statement.
PL/SQL is a block-structured language composed of procedures, functions, and anonymous blocks that make up a PL/SQL program.
Each logical block corresponds to a problem or subproblem to be solved.
PL/SQL CODE
Sample program
PL/SQL can be use within SQL, embedded SQL, or PL/SQL routines.
PL/SQL is a technology and can be placed in ORACLE RDBMS or ORACLE application tools.
PL/SQL only requires the executable part to run.
You can nest sub-blocks in the executable and exception-handling parts of a PL/SQL block or subprogram but NOT the DECLARATIVE part.
PL/SQL IN THE ORACLE RDBMS
PL/SQL resides in two environments:
ORACLE RDBMS & ORACLE APPLICATION TOOLS (ORACLEForms,
Precompilers, SQL*DBA, SVRMGR, SQL*PLUS, and Oracle Reports)
PL/SQL supports all the SQL datatypes
You can use upper, lower, or mixed case to write identifiers. PL/SQL is not case sensitive except within string or character literals.
PL/SQL VARIABLES
Two types of Variables
NOTES:
Declare and initialize within the declaration section.
Assign new values to variables within the executable section.
Input values from the user environment with substitution parameters.
Can store and change values within a PL/SQL block
DECLARING SCALAR VARIABLES
Examples in a DECLARE BLOCK
DECLARE
staff_count BINARY_INTEGER :=0; --use for staff count
staff_salary NUMBER (11,2); --used to store total salaries
emp_gross NUMBER (9,2) := 0; --used to compute employee gross
new_name VARCHAR2(25); --used to store new employee name
job_status CHAR(10); --stores new job status for updates
company_name CONSTANT VARCHAR2 (17) := `URCOMPANY NAME';
/*(this declares a constant for the company name which never
changes throughout the PL/SQL block) */
EXECUTION
EXCEPTION (optional)
END;
The above variables are declared to store numeric and alphanumeric data.
The criteria for declaring identifiers is:
Name of the identifier
Decide whether it is a variable or constant
Decide the datatype of the identifier (scalar or composite)
Determine if it will allow for nulls or have an initial value.
Identifiers cannot exceed 30 characters
SCALAR VARIABLES
Declaring DATE and BOOLEAN variables
DECLARE
hire_date DATE := SYSDATE; --Initialize hire date to today
emp_date DATE := SYSDATE + 30; --Set employ date to 30 days from now.
years_emp POSITIVE; -- value must be greater than 0.
emp_retired BOOLEAN NOT NULL := FALSE; -- set flag to false (not retired)
emp_name VARCHAR2(20);
wages NUMBER(9,2);
emp_id NUMBER(4);
Declared variables are referenced within the executable section according to the scoping rules.
NOTE:
You can use SELECT or FETCH statements to have ORACLE assign values to a variable within an PL/SQL block.
Select name, salary INTO emp_name, wages from staff where id = emp_id;
REFERENCING VARIABLES
Scoping Examples
DECLARE
vendor_name VARCHAR(40) := `BCI Inc.';
vendor_status VARCHAR(15) := `EXCELLENT';
BEGIN
DECLARE
vendor_name CHAR(30) := `MicroLynk Corp.';
vendor_address VARCHAR(35) := `111 Ocean Dr.';
BEGIN
vendor_name vendor_address vendor_status
END;
vendor_name vendor_address vendor_status
END;
SCOPING RULES
An identifier is visible in the block in which it is declared all nested sub-blocks, procedures, and functions unless rule 2 applies.
If an identifier declared in an enclosing block is re-declared in a sub-block, the original identifier declared in the enclosing block is no longer visible in the sub-block. However, the newly declared identifier has the rules of scope defined in
rule 1.
USING COMPOSITE VARIABLES
Declaring Records
/* Using composite variables, create an employee record in the declare */
/* section, initialize appropriate variables in the declare section */
/* and select column values from the staff table and place these values */
/* in the appropriate declared variables. */ -- SEE PL12.sql
declare
TYPE employee_record_type is record
( first_name varchar2(10) not null := ' ',
last_name varchar2(15) not null := ' ',
dept number(4),
age number(3),
salary number(7,2),
years_emp number(2) := 0,
comm staff.comm%TYPE);
staff_record employee_record_type;
BEGIN
select name, dept,name,years,salary,years,comm
into staff_record.first_name,staff_record.dept,staff_record.last_name,
staff_record.age,staff_record.salary,staff_record.years_emp,
staff_record.comm from staff where id = 20;
END;
/
User defined records are declared in two steps
- You define a RECORD type
- You declare user-defined records of that type
Notice that the field declarations are like variable declarations. Each field has a unique name and specific datatype and can be initialized.
** If a query returns more than one ROW with a select - AN ERROR OCCURS **
Any field may be defined to have the NOT NULL constraint.
The %TYPE attribute allows you to define a field using the same datatype as defined in a table.
To reference individual fields in the record: staff_record.first_name
PL/SQL RECORDS PROCESSING
%ROWTYPE attribute
Task: declare a variable to store the same information about the organization
as is currently stored in the ORG table.
DECLARE
org_record org%ROWTYPE;
BEGIN
select DEPTNAME into ORG_RECORD.DEPTNAME from ORG
WHERE DEPTNUMB = 10;
END;
The %ROWTYPE variable allows you to declare the data structure of a database table.
The columns in the table row and corresponding fields in the record will have the same names and datatypes.
Provides a mechanism for storing data about tables where the underlying datatypes are unknown.
ASSIGNING VALUES TO VARIABLES
ORACLE>ACCEPT local_id PROMPT `ENTER EMPLOYEE ID'
DECLARE
max_salary NUMBER(11,2) := 0;
new_company_name VARCHAR2(25);
staff_record staff%ROWTYPE;
BEGIN
/* set the maximum salary equal to the maximum salary in staff */
select max(salary) into max_salary from staff;
/* set the new company name = to BCI LTD. */
new_company_name := `BCI LTD.';
/* Store the basic information about a new employee within the
staff_record record structure */ -- SEE PL14.sql
staff_record.id := &local_id; -- See NOTES below
staff_record.name := `Dave Stallman';
staff_record.dept := 10;
staff_record.job := MGR';
staff_record.years := 15;
staff_record.salary := 45000.00;
staff_record.comm := 4000.00
INSERT INTO STAFF(id,name,dept,,job,years,salary,comm)
VALUES(staff_record.id,staff_record.name,staff_record.dept,
staff_record.job,staff_record.years,staff_record.salary,
staff_record.comm);
END;
Try the following values with pl14.sql
staff_record.id := 1090; -- This is a literal value
staff_record_id := &local -- This is a substitution parameter
staff_record_id = &local_id -- This is a local variable created by an ACCEPT
EXERCISE 1
TASK:
· Create a PL/SQL block that adds a new department 77 into your org table. Input the department number, department name and
location from your terminal using SQL*PLUS substitution
parameters. The values are:
Department number = 77
Department name = `CORPORATE'
Department Location = `SAN ANTONIO'
(ADD OTHER VALUES FOR OTHER COLUMNS IN THE ORG
TABLE AS DESIRED)
· Once inserted into the org table, select the row to view the data.
Don't forget that substitution parameters that are alphanumeric values should have
single quotes around them, i.e.
department_name org.deptname%type := `&name';
See plsqlab1.sql
DEFINING COMPOSITE VARIABLES - TABLES
Assigning values to a declared TABLE variable
Task: Look up bonus based upon amount of commission made by
an employee and update the employee column bonus.
SQL>ACCEPT g_emp_id PROMPT `ENTER EMPLOYEE ID'
DECLARE
TYPE bonus_table_type IS TABLE OF NUMBER(9,2)
INDEX BY BINARY_INTEGER;
g_emp_id staff.id%type := &empid;
bonus_tab bonus_table_type;
BEGIN
/* bonus_tab is loaded with appropriate dollar amounts */
FOR I IN 1..10 LOOP
bonus_tab(I) := &anumber + I;
end loop;
.... Find an employees commission and based upon that
you find an appropriate bonus value.
. Since we have not covered loops or if-then-else logic
. - this is an incomplete example. DO NOT PANIC we will
. Cover all of these statements in the next pages. Anyway
. After we find a proper bonus value we can update the
. Employees bonus by doing the following update using
. The plsql table we created earlier.
UPDATE staff
set bonus = bonus_tab (i)
where id = g_emp_id;
NOTES:
When defining a PL/SQL table, you first define a table type, then declare PL/SQL tables of that type as indicated above.
The identifier bonus_tab represents an entire PL/SQL table of that type.
The subscript may is any valid negative, zero, or positive value.
USING EXPRESSIONS AND OPERATORS TO ASSIGN VALUES
Examples
/* Increment the index for a loop */
staff_count := staff_count + 1;
/* Validate an existing employee id to ensure it has a value */
v_valid := (g_emp_id IS NOT NULL);
/* Convert employee name to upper case */
emp_lastname := UPPER(emp_lastname);
/* Set the delivery date to one month from the purchase of item */
ship_date := order_date + 30;
/* Set a flag to TRUE or FALSE based upon whether two numbers
are equal
v_flag := (v_gross = v_total);
NOTE:
Do not build PL/SQL expressions using SQL Group or Built-in functions such as SUM, AVG, or COUNT.
DATATYPE CONVERSIONS
/* Concatenate the employee last name with employee first name)
v_string := v_emp_lastname || v_emp_firstname;
/* Add 99 ( a character string) to 100 ( a number);
v_sum := `99' + 100;
NOTE:
When building assignments, PL/SQL will automatically convert expressions.
INPUT AND OUTPUT VALUES FOR VARIABLES
Accept and display a value according to the user environment.
/* Prompt user to input a monthly salary into g_sal */
SQL>ACCEPT g_sal PROMPT `ENTER MONTHLY SALARY'
/* Declare a SQL*PLUS global variable with the SQL*PLUS VARIABLE command */
SQL> VARIABLE g_year_sal NUMBER
DECLARE
/* Within the PL/SQL block, embed the SQL*PLUS substitution
parameter wherever it is needed as input, referencing it with
the ampersand (&) prefix. */
emp_sal NUMBER(9,2) := &g_sal;
BEGIN
:g_year_sal := emp_sal * 12;
....
....
END;
/
/* Outside the PL/SQL block, print the output value on the screen with
the SQL*PLUS PRINT command. */
SQL> PRINT g_year_sal
NOTE:
A colon : within a variable (:g_year_sal) tells PL/SQL to go look for the particular global variable outside of PL/SQL.
EXERCISE 2
TASK:
· Create a PL/SQL block that computes the total compensation for
an employee based on salary, commission and a bonus which is
calculated as a percent of commission.. The total compensation is
calculated by taking the salary plus commission plus the
calculated bonus. The bonus is calculated by multiplying
commission by 5 percent.
· Input the employee number from your terminal using SQL*PLUS substitution parameter. Using the employee number
select the current salary and commission from the staff table.
· Output the total compensation amount to your screen using a
SQL*PLUS global variable.
See plsqlab2.sql
RETRIEVING DATA
Using the SELECT clause
Task: Retrieve the employee name and salary for the specified employee.
SQL>ACCEPT p_emp_id PROMPT `ENTER EMPLOYEE ID'
DECLARE
emp_id staff.id%TYPE :=&p_emp_id;
emp_name staff.name%TYPE;
emp_dept staff.dept%TYPE;
emp_salary staff.salary%TYPE;
BEGIN
SELECT dept,id,name,salary
INTO emp_dept,emp_id,emp_name,emp_salary
FROM staff
WHERE id = emp_id;
....
END;
/
NOTES:
Make sure that the datatypes are compatible if declaring datatypes.
Specify the same number of output variables in the INTO clause as database columns in the SELECT statement
PL/SQL SELECT STATEMENTS
Examples:
Task: Compute the sum of the salaries of all employees in the specified
department. See PL20.sql
SQL> ACCEPT p_dept_no PROMPT `ENTER DEPARTMENT NO'
DECLARE
dept_no staff.dept%TYPE :=&p_dept_no;
sum_salary staff.salary%TYPE;
BEGIN
SELECT sum(salary)
INTO sum_salary
FROM staff
WHERE dept = dept_no;
....
END;
/
NOTES:
When using PL/SQL SELECT statements, you must retrieve exactly one row; otherwise, an exception error is raised.
Alternatively, fetch multiple rows one by one in a loop by declaring an explicit cursor.
Typical SELECT exception codes are:
-1422 = TOO_MANY_ROWS
+1403 = NO_DATA_FOUND
PL/SQL INSERT STATEMENTS
Manipulating Data
Task: Add a new employee to the staff table for a specified department. See PL21.sql.
SQL>ACCEPT p_dept_no PROMPT `ENTER DEPARTMENT NUMBER:'
DECLARE
emp_id staff.id%TYPE;
emp_name staff.name%TYPE := `JOHN SULL';
emp_dept staff.dept%TYPE := &p_dept_no;
emp_job staff.job%TYPE := `PROG';
emp_years staff.years%TYPE := 0;
emp_salary staff.salary%TYPE;
emp_comm staff.comm%TYPE;
BEGIN
SELECT max(id) INTO emp_id from staff;
emp_id := emp_id + 1;
INSERT INTO staff (id,name,dept,job,years,salary,comm)
VALUES(emp_id,emp_name,emp_dept,emp_job,emp_years,
emp_salary,emp_comm);
COMMIT WORK;
END;
PL/SQL allows you to insert from a PL/SQL record into a database row
field by field or specify values through input from PRO*C, SQL*PLUS, or
other ORACLE environments.
PL/SQL UPDATE PROCESSING
Example
Task: Change/update the salary for an employee in the staff table and
calculate their commission as 5% of their salary. See PL22.sql
SQL> ACCEPT p_emp_id PROMPT `ENTER EMPLOYEE ID'
SQL> ACCEPT p_salary PROMPT `ENTER THE NEW SALARY'
DECLARE
emp_id staff.id%TYPE := &p_emp_id;
emp_salary staff.salary%TYPE := &p_salary;
emp_comm staff.comm%TYPE;
BEGIN
UPDATE staff
SET salary = emp_salary, comm = (salary * .05)
WHERE id = emp_id;
COMMIT WORK;
END;
EXERCISE 3
TASK:
· Create a PL/SQL block that updates the location of department
number 10 to HOUSTON in the org table.
· Input the department number, and location from your terminal
using SQL*PLUS substitution parameters.
· After the update, select the row from the org table.
See plsqlab3.sql
PL/SQL DELETE PROCESSING
Example
Task: Delete the specified employee. See PL23.sql
SQL> ACCEPT p_emp_id PROMPT `ENTER EMPLOYEE ID'
DECLARE
emp_id staff.id%TYPE := &p_emp_id;
BEGIN
DELETE FROM staff
WHERE id = emp_id;
COMMIT WORK;
END;
/EXERCISE 4
TASK:
· Create a PL/SQL block that deletes employee number 300 in the
staff table
· Input the employee number from SQL*PLUS.
· After the delete, make sure the row is gone from the staff table.
See plsqlab4.sql
PL/SQL CONTROL STRUCTURES
IF-THEN-ELSE
Task: Set the bonus for a specified employee based upon the following
commission scale: See PL24.sql
commission bonus = % of commissions
>= 500.01 10%
< 500.01 >= 400.00 8%
< 400.01 >= 300.00 6%
< 300.01 >= 200.00 4%
< 200.01 >= 100.00 2%
< 100.01 >= 0.00 0%
SQL>ACCEPT g_emp_id PROMPT `ENTER EMPLOYEE ID'
DECLARE
bonus staff.comm%TYPE;
commission staff.comm%TYPE;
emp_id staff.id%TYPE := &g_emp_id;
bonus_amt number(5,2);
BEGIN
select comm INTO commission
FROM staff
where id = emp_id;
IF (commission >-1 and commission < 100.01)
THEN bonus_amt := 0;
ELSIF (commission >= 100.01 and commission < 200.01)
THEN bonus_amt := .02 * commission;
ELSIF (commission >= 200.01 and commission < 300.01)
THEN bonus_amt := .04 * commission;
ELSIF (commission >= 300.01 and commission < 400.01)
THEN bonus_amt := .06 * commission;
ELSIF (commission >= 400.01 and commission < 500.01)
THEN bonus_amt := .08 * commission;
ELSE
bonus_amt := .10 * commission;
END IF;
UPDATE staff
set bonus = bonus_amt
WHERE id = emp_id;
COMMIT WORK;
END;
EXERCISE 5
TASK:
· Create a PL/SQL block that will increase an employee's salary
(employee number 60 in the staff table) based upon their current
salary as listed below:
If salary < $10,000.00 increase it by 10%.
If salary is between $10,000.01 and $15,000.00 increase
their salary by 7%.
If salary > $15,000.00 increase salary by 5%.
· Input the employee number from your terminal using SQL*PLUS substitution parameters.
· After the update, select the row from the staff table.
See plsqlab5.sqlPL/SQL ITERATIVE PROCESSING
Simple Loop
Task: Create the next ten purchase order numbers by incrementing
the maximum PO value currently in the puorder table and put
the current date into the new row. See PL25.sql
DECLARE
new_po puorder.po%TYPE;
cur_date puorder.po_date%TYPE;
countr NUMBER(2) := 1;
BEGIN
LOOP
SELECT max(po) + 1 INTO new_po
FROM puorder;
INSERT INTO puorder(po,po_date)
VALUES( new_po,SYSDATE);
countr := countr + 1;
EXIT WHEN countr > 10;
END LOOP;
END;
In order for the script pl25.sql to work you must create the following table.
1. CREATE TABLE PUORDER
(PO NUMBER(6) NOT NULL,
PO_DATE DATE);
INSERT INTO PUORDER
VALUES (10,SYSDATE);
The simple LOOP statement will repeat a sequence of statements until the EXIT statements WHEN condition is TRUE.
PL/SQL ITERATIVE PROCESSING
FOR Loop
Task: Create the next ten purchase order numbers by incrementing
the maximum PO value currently in the puorder table and put
the current date into the new row. See PL26.sql
DECLARE
new_po puorder.po%TYPE;
cur_date puorder.date%TYPE;
countr NUMBER(2) := 1;
BEGIN
FOR I IN 1..10 LOOP
SELECT max(po) + 1 INTO new_po
FROM puorder;
INSERT INTO puorder(po,po_date)
VALUES( new_po,SYSDATE);
END LOOP;
END;
Control of the numeric FOR loop is done through its numeric index.
It is also possible to utilize the decrement option with the numeric FOR Loop. I.e. FOR I IN REVERSE 10..1
PL/SQL ITERATIVE PROCESSING
WHILE Loop
Task: Create the next ten purchase order numbers by incrementing
the maximum PO value currently in the puorder table and put
the current date into the new row. See PL27.sql
DECLARE
new_po puorder.po%TYPE;
cur_date puorder.date%TYPE;
countr NUMBER(2) := 1;
BEGIN
WHILE countr <= 10 LOOP
SELECT max(po) + 1 INTO new_po
FROM puorder;
INSERT INTO puorder(po,po_date)
VALUES( new_po,SYSDATE);
countr := countr + 1;
END LOOP;
END;
EXERCISE 6
TASK:
· Create a PL/SQL block that creates the next ten employee
numbers by incrementing the maximum employee value currently
in the staff table and load a pl/sql table called emp_table with this
data. Then create the next ten employees and insert them into the
staff table. Use the employee numbers in the emp_table and
create the necessary name, dept, job, years, salary & commission
fields for these 10 new employees using either substitution
parameters or constants.
This is an exercise in using loops. Try to use two (2) different kind
of loops as shown in the earlier exercise. Use the first loop to
find a maximum employee id and load a plsql table with the next
ten employee numbers. Note, you have not inserted any new
employees into the staff table yet.
Create another loop which now inserts 10 new employees into
the staff table using the plsql table which has the 10 employee
ids.
See plsqlab6.sql
PL/SQL ITERATIVE PROCESSING
Exiting Nested Loops AND Review of PL/SQL concepts. This is not a working
example. It is only used to show the different plsql concepts covered up to this
point. Notice that you can lable outer and inner loops with the label command
<<outer_loop>> etc, and you can branch out of all loops through an exit command.
Task: Count the number of ORDERS for a specific customer using the temp table and then INSERT all ORDERS in the order table. This requires that you read all ORDER ITEMS in the tempitem table and INSERT these rows into
the orditems table. See PL28A.sql
SQL>ACCEPT g_cust_no PROMPT `PLEASE ENTER CUSTOMER NO'
DECLARE -- Notice the different datatypes we can use in pl/sql
cur_order order%ROWTYPE;
no_orders NUMBER(4);
min_order_no NUMBER(6):= 0;
cust_no customer.cust_no%TYPE := &g_cust_no;
next_order order.order_no%TYPE := 0;
cur_orditems orditems%ROWTYPE;
no_orditems NUMBER(6);
min_item_no orditems.item_no%TYPE;
BEGIN
<< outer_loop >> -- Notice below is a singleton select
SELECT count(*),min(order_no) INTO no_orders,min_order_no
FROM temp
WHERE cust_no = temp.cust_no and
min(order_no) > min_order_no;
FOR I IN 1..no_orders LOOP
INSERT INTO order (min_order_no,SYSDATE,cust_no);
SELECT count(*),min(item_no) INTO no_orditems,min_item_no
FROM tempitems GROUP BY order_no
HAVING min(order_no) > min_order_no;
<< inner_loop >>
FOR J IN 1..no_orditems LOOP
INSERT INTO orditems(min_order_no,min_item_no),
VALUES (cur_orders.desc,cur_orders.qty)
EXIT outer_loop WHEN no_orders > 31;
END LOOP inner_loop;
END LOOP outer_loop;
END;
PL/SQL EXCEPTIONS
Error Handling
DECLARE
BEGIN
EXCEPTION
END;
Every ORACLE error has a number, but PL/SQL handles errors by their
exception name. Whenever a PL/SQL program violates an ORACLE rule
or exceeds a system dependent unit an internal exception is raised implicitly.
PL/SQL has 3 types of exceptions:
 Pre-defined ORACLE Error - some of the most common standard ORACLE errors defined in PL/SQL.
 Non-predefined ORACLE error - any other standard ORACLE error
 User-defined Error - a condition that the application determines is abnormal
ERROR PROCESSING
Trapping exceptions through Predefined Exceptions
DECLARE
BEGIN
EXCEPTION
WHEN exception 1 (OR exception 2 ...) THEN
statement 1;
statement 2;
... WHEN exception3 (OR exception4 ...) THEN
statement 1;
... statement 2;
WHEN OTHERS THEN
statement1;
statement2;
...
PL/SQL PREDEFINED EXCEPTIONS ARE:
Exception Name Oracle Error Description
NO_DATA_FOUND ORA-01403 Single Row Select returned no data.
TOO_MANY_ROWS ORA-01427 Single row SELECT returned more than
one row
INVALID_CURSOR ORA-01001 Illegal cursor operation occurred
VALUE_ERROR ORA-06502 Arithmetic,conversion,truncation, or
constraint error occurred
INVALID_NUMBER ORA-01722 conversion of a character string to a
number failed
ZERO_DIVIDE ORA-01476 Attempted to divide by zero
DUP_VAL_ON_INDEX ORA-00001 Attempted to insert a duplicate value
LOGON_DENIED ORA-01017 Invalid username/password used.
NOT_LOGGED_ON ORA-01012 ORACLE call without ORACLE logon
PROGRAM_ERROR ORA-06501 PL/SQL had an internal problem
STORAGE_ERROR ORA-06500 PL/SQL memory full or corrupted
TIMEOUT_ON_RESOURCE ORA-00051 Resource not available in time
PL/SQL EXCEPTIONS
Two ways to handle any exception
Method 1 - Task: Delete all employees tied to a specific dept. See PL31.sql
SQL> ACCEPT p_dept_no PROMPT `ENTER DEPARTMENT NO'
DECLARE
t_dept_no STAFF.DEPT%type := &p_dept_no;
temp_dept staff.dept%type;
BEGIN
select distinct dept into temp_dept from staff
where dept = t_dept_no;
delete from staff
where dept = t_dept_no;
commit work;
EXCEPTION
WHEN NO_DATA_FOUND then
rollback work;
insert into exception_table(message)
values(`Department number is invalid.');
WHEN OTHERS THEN
rollback work;
insert into exception_table(message)
values('Other error occurred.');
commit work;
END;
/
For this script to work, you must create the exception_table as describe below:
CREATE TABLE EXCEPTION_TABLE
(MESSAGE VARCHAR2(300));
Exception processing handles unanticipated exception with the OTHERS
clause.
Any error may be trapped including a corresponding routine within the
exception handling section of the PL/SQL block.
PL/SQL ERROR PROCESSING
Trapping Non-Predefined Oracle Exceptions
Task: Delete an employee. Ensure that there are no employees with that
department number left in the table. See PL32.sql
SQL> ACCEPT p_dept_no PROMPT `ENTER DEPARTMENT NUMBER'
DECLARE
t_dept_no staff.dept%TYPE :=&p_dept_no;
e_dept_error EXCEPTION;
/* -2292 is ORACLE error number for integrity constraint violated */
PRAGMA EXCEPTION_INIT (e_dept_error, -2292);
BEGIN
DELETE FROM staff
WHERE dept = t_dept_no;
COMMIT WORK;
EXCEPTION
WHEN e_dept_error THEN
ROLLBACK WORK;
INSERT INTO exception_table(message)
VALUES(`Referential integrity constraint violated.');
COMMIT WORK;
WHEN OTHERS THEN
ROLLBACK WORK;
INSERT INTO exception_table(message)
VALUES(`Other error occurred.');
COMMIT WORK;
END;
1.Non-predefined Oracle errors are declared first.
e_dept_error EXCEPTION;
2. Associate the declared exception with the Standard Oracle error number using
the EXCEPTION_INIT pragma statement.
PRAGMA EXCEPTION_INIT (e_dept_error, -2292);
PL/SQL ERROR PROCESSING
Raising User-Defined Exceptions
Task: Delete a department in the org table. Ensure that the department is not
deleted if their are still employees assigned to this department number. First count the number of employees with this department #. If the total employee count is greater than 0 stop processing because we need to abort the department number deletion in the ORG table.See PL33.sql
SQL> ACCEPT p_dept_no PROMPT `ENTER DEPARTMENT NO'
DECLARE
t_dept_no org.deptnumb%TYPE:=&p_dept_no;
e_dept_error EXCEPTION;
countr NUMBER(5) :=0;
BEGIN
SELECT count(*) INTO countr FROM staff
WHERE dept = t_dept_no;
IF countr >0 THEN
RAISE e_dept_error;
END IF;
DELETE FROM ORG
WHERE DEPTNUMB = t_dept_no;
COMMIT WORK;
EXCEPTION
WHEN e_dept_error THEN
ROLLBACK WORK;
INSERT INTO exception_table(message)
VALUES(`There are still employees with this department no.');
COMMIT WORK;
WHEN OTHERS THEN
ROLLBACK WORK;
INSERT INTO exception_table(message)
VALUES(`Other error occurred.');
COMMIT WORK;
END;
This User Exception error is declared for a user-defined abnormal condition.
When exiting a User Defined Exception routine or a Non-Predefined Oracle
exception routine, the end of the program shows a normal condition code.
PL/SQL ERROR PROCESSING
Storing the Oracle SQLCODE for error exceptions
Task: Store the error code and error message for any needed exceptions
DECLARE
...
v_error_code NUMBER;
OR
v_error_code sqlca.sqlcode%TYPE;
v_error_message VARCHAR2(255);
BEGIN
...
..
EXCEPTION
WHEN OTHERS THEN
v_error_code := SQLCODE;
v_error_message := SQLERRM;
ROLLBACK WORK;
INSERT INTO exception_table(message)
VALUES(TO_CHAR(v_error_code) || `:' ||v_error_message);
COMMIT WORK;
END;
You can trap information on unanticipated exceptions by referencing the
SQLCODE reporting function.
SQLCODE DESCRIPTION
0 No exception encountered
1 User-defined exception
+1403 NO_DATA_FOUND exception
<0 Any other ORACLE exception
You may also store the complete ORACLE reference message by utilizing
the SQLERRM reporting function as shown above.
EXERCISE 7
TASK:
· 1. Create a PL/SQL block that uses EXCEPTION HANDLING. The PL/SQL
block will accept as input an (incorrect job title, `CEO' from SQL*PLUS. Test
for a `NOT FOUND' condition using a predefined Oracle error name. Put
the error message `BOGUS JOB TITLE' into a SQL*PLUS defined variable.
If the information is correct, enter the employee information into the staff
table. Using SQL*PLUS, prompt for the employee name, dept, job, years,
salary and commission. Retrieve a new employee id by selecting max(id) to
get the next employee id.
· 2. Create a PL/SQL block which uses EXCEPTION HANDLING and accepts
as input an invalid Department Number (not 10, 15, 20, 38 etc.) from
SQL*PLUS and declare your own exception handling error routine. Put the
error message, `DEPARTMENT NUMBER IS INVALID' into an SQL*PLUS
defined variable
See plsqlab7.sql OR plsqlab7a.sql
PL/SQL ERROR PROCESSING
Propagating Exceptions
Task: Allow the calling environment to handle trapping exceptions
1. SQL*PLUS displays unhandled exception numbers to the screen.
2. ORACLE FORMS are handled through triggers by using ERROR_CODE and
ERROR_TEXT packaged functions.
3. PRO*C handles exceptions through the SQLCA structure.
4. PL/SQL handles exceptions through the enclosing block.
PL/SQL ERROR PROCESSING
Propagating Exceptions Example
BEGIN
...
BEGIN
......
IF(commission >0 and commission < 100.01)
THEN RAISE BONUS_AMTA;
ELSIF IF commission < 200.01
THEN RAISE BONUS_AMTB;
ELSIF commission < 300.01
THEN RAISE BONUS_AMTC;
ELSIF commission < 400.01
THEN RAISE BONUS_AMTD;
ELSIF commission < 500.01
THEN RAISE BONUS_AMTE;
ELSE
bonus_amt := 0;
END IF;
EXCEPTION
WHEN BONUS_AMTA THEN
bonus_amt := 1.10 * salary;
.......
WHEN BONUS_AMTC THEN
bonus_amt := 1.12 * salary + comm;
END;
..
RAISE;
..
EXCEPTION
WHEN BONUS_AMTB THEN
bonus_amt := .10 * commission;
.....
WHEN BONUS_AMTC THEN
bonus_amt := .08 * commission;
......
end;
NOTE: RAISE causes control to pass to the next BONUS_AMTC so that
a normal processing code does not leave the program.
PL/SQL CURSOR PROCESSING
Objectives
 At the end of this section you will be able to:
 Identify explicit and implicit cursor attributes
 Process a query using an explicit cursor.
 Retrieve rows from the active set of rows returned by a query.
 Use implicit cursor attributes to determine the outcome of an operation.
CURSOR PROCESSING
Explicit Cursors
DECLARE
Cursor C1 is
Select id,name,salary
from staff
where dept = 10;
BEGIN
OPEN C1;
Loop
....
....
FETCH C1;
....
....
/*Process row */
....
/* end Loop */
CLOSE C1;
More about Cursors:
 Set of rows that satisfy the search criteria of a query can consist of zero, one, or many rows
 When the query could possibly return many rows, declare and handle rows with an explicit cursor
CURSOR PROCESSING
Declaring the Cursor
Task: Retrieve all employees in a specified department. See PL40.sql
DECLARE
....
v_id staff.id%TYPE;
v_dept staff.dept%TYPE :=&p_dept_no;
v_salary staff.salary%TYPE;
v_comm staff.comm%TYPE;
v_total_pay NUMBER(11,2);
CURSOR pay_cursor IS
select id,dept,salary,comm
from staff
where dept = v_dept;
BEGIN
....
Declare the cursor with an appropriate name related to the select
Do not include the INTO clause within the cursor declaration
Variables referenced in the select statement must be declared before the cursor declaration
CURSOR PROCESSING
Open Cursor statement
Task: Retrieve all employees in a specified department. See PL41.sql
SQL> ACCEPT p_dept_no PROMPT `ENTER DEPARTMENT NO'
DECLARE
....
v_id staff.id%TYPE;
v_dept staff.dept%TYPE;
v_salary staff.salary%TYPE;
v_comm staff.comm%TYPE;
v_total_pay NUMBER(11,2);
CURSOR pay_cursor IS
select id,dept,salary,comm
from staff
where dept = v_dept;
BEGIN
v_dept = &p_dept_no
OPEN pay_cursor
....
Open the cursor after specifying values for all input variables.
CURSOR PROCESSING
Declaring the Cursor
Task: Retrieve all employees in a specified department. See pl41.sql
DECLARE
....
v_id staff.id%TYPE;
v_name staff.name%TYPE;
v_dept staff.dept%TYPE;
v_salary staff.salary%TYPE;
v_comm staff.comm%type;
CURSOR pay_cursor IS
select id,dept,salary,comm
from staff
where dept = v_dept;
BEGIN
OPEN PAY_CURSOR;
Loop
FETCH pay_cursor
INTO v_id,v_dept,v_salary,v_comm;
EXIT WHEN pay_cursor %NOTFOUND;
. - Process data here etc. etc.
End loop;
When fetching a row from a cursor you may inspect the cursor attributes by
utilizing the following cursor attributes in PL/SQL.
%ISOPEN - Boolean attribute that evaluates to TRUE if the cursor
is open
%NOTFOUND - Boolean attribute that evaluates to TRUE if the most
recent FETCH does not return a row.
%FOUND - Boolean attribute that evaluates to TRUE until the
most recent FETCH does not return a row
%ROWCOUNT - Numeric attributes that evaluates to the total number
of rows returned so far.
CURSOR PROCESSING
Using Cursor attributes with EXPLICIT CURSORS - %NOTFOUND
Task: Calculate the total pay for a specified department. Store the total
pay in a separate table for use later. See PL41.sql
SQL> ACCEPT p_dept_no PROMPT `ENTER DEPARTMENT NO'
DECLARE
v_name staff.name%TYPE;
v_id staff.id%TYPE;
v_dept staff.dept%TYPE;
v_salary staff.salary%TYPE;
v_comm staff.comm%TYPE;
v_gross_pay NUMBER(9,2) :=0;
v_total_pay NUMBER(11,2) :=0;
CURSOR pay_cursor IS
select id,name,dept,salary +NVL(comm,0)
from staff
where dept = v_dept;
BEGIN
v_dept=&p_dept_no;
OPEN pay_cursor;
LOOP
FETCH pay_cursor
INTO v_id,v_name,v_dept,v_gross_pay;
EXIT WHEN pay_cursor %NOTFOUND;
v_total_pay := v_total_pay + v_gross_pay;
INSERT INTO temppay(deptno,dept_pay)
VALUES(v_dept,v_total_pay);
END LOOP;
CLOSE pay_cursor;
END;
For this script to work, you must create the following table:
CREATE TABLE TEMPPAY
(DEPTNO NUMBER(4),
DEPT_PAY NUMBER(11,2));
Using the %NOTFOUND attribute allows you to exit a loop when there are no more records to be fetched in the cursor results table.
CURSOR PROCESSING
Using Cursor attributes with EXPLICIT CURSORS - %FOUND
Task: Calculate the total pay for a specified department. Store the total
pay in a separate table for use later. (see pl42.sql)
SQL> ACCEPT p_dept_no PROMPT `ENTER DEPARTMENT NO'
DECLARE
....
v_id staff.id%TYPE;
v_name staff.id%TYPE;
v_dept staff.dept%TYPE;
v_salary staff.salary%TYPE;
v_comm staff.comm%TYPE;
v_gross_pay NUMBER(9,2) :=0;
v_total_pay NUMBER(11,2) :=0;
CURSOR pay_cursor IS
select id,name,dept,salary +NVL(comm,0)
from staff
where dept = v_dept;
BEGIN
v_dept=&p_dept_no;
OPEN pay_cursor;
FETCH pay_cursor
INTO v_id,v_name,v_dept,v_gross_pay;
WHILE pay_cursor %FOUND LOOP
v_total_pay := v_total_pay + v_gross_pay;
INSERT INTO temppay(deptno,dept_pay)
VALUES(v_dept,v_total_pay);
fetch pay_cursor into v_id,v_name,v_dept,v_gross_pay;
END LOOP;
CLOSE pay_cursor;
COMMIT WORK;
END;
A variety of looping mechanisms can be used for retrieving the rows in a cursor.
The example above uses the WHILE statement.
CURSOR PROCESSING
Using Cursor attributes to retrieve an exact number of rows
Task: Calculate the total pay for a specified department. Store the total
pay in a separate table for use later. See PL43.sql
SQL> ACCEPT p_dept_no PROMPT `ENTER DEPARTMENT NO'
DECLARE
....
v_id staff.id%TYPE;
v_dept staff.dept%TYPE;
v_salary staff.salary%TYPE;
v_comm staff.comm%TYPE;
v_gross_pay NUMBER(9,2) :=0;
v_total_pay NUMBER(11,2) :=0;
CURSOR pay_cursor IS
select id,salary +NVL(comm,0)
from staff
where dept = v_dept;
BEGIN
v_dept=&p_dept_no;
OPEN pay_cursor;
LOOP
FETCH pay_cursor
INTO v_id,v_gross_pay;
v_total_pay := v_total_pay + v_gross_pay;
INSERT INTO temppay(deptno,dept_pay)
VALUES(v_dept,v_total_pay);
EXIT WHEN pay_cursor %ROWCOUNT = 25;
EXIT WHEN pay_cursor %NOTFOUND;
END LOOP;
CLOSE pay_cursor;
COMMIT WORK;
END;
By using the %ROWCOUNT variable you may control the number of rows
fetched within a cursor
CURSOR PROCESSING
Using Cursor FOR LOOP commands
Task: Calculate the total pay for a specified department. Store the total
pay in a separate table for use later. See PL44.sql
SQL> ACCEPT p_dept_no PROMPT `ENTER DEPARTMENT NO'
DECLARE
....
v_id staff.id%TYPE;
v_salary staff.salary%TYPE;
v_comm staff.comm%TYPE;
v_gross_pay NUMBER(9,2) :=0;
v_total_pay NUMBER(11,2) :=0;
v_dept staff.dept%TYPE;
CURSOR pay_cursor IS
select id, salary, comm
from staff
where dept = v_dept;
BEGIN
v_dept=&p_dept_no;
FOR pay_record IN pay_cursor LOOP
v_total_pay := v_total_pay + (pay_record.salary
+ pay_record.comm);
INSERT INTO temppay(deptno,dept_pay)
VALUES(v_dept,v_total_pay);
END LOOP;
END;
You do not need to declare v_id,v_salary, or v_comm because the FOR loop creates the variables for you. Pay_record is a record variable which has matching column names and datatypes based upon the cursor (pay_cursor) it points too.
You can also retrieve an exact number of rows by using the CURSOR FOR LOOP
command. This cursor determines when to exit as well as performs the other
cursor functions such as OPEN, FETCH, and CLOSE.
NOTE: Do not DECLARE the record that controls the loop (i.e. pay_record).
CURSOR PROCESSING
Update the current row using the WHERE CURRENT OF clause
Task: Update any employee who makes more than $10,000.00 a year and is in department 10, 20, or 84 and has commissions greater than at least 10% of their gross total pay Give them a 10% increase in salary. See PL46.sql
SQL> ACCEPT p_dept_no PROMPT `ENTER DEPARTMENT NO'
DECLARE
countr number(3) := 0;
v_dept staff.dept%TYPE :=&p_dept_no;
new_comm staff.comm%TYPE;
v_gross_pay number(9,2) :=0;
totcount number(4) :=0;
v_total_pay number(11,2) :=0;
cursor pay_cursor is
select dept,id,name,salary,comm
from staff
where dept in (10,20,84) and salary > 10000
for update of comm,salary,dept;
BEGIN
FOR pay_record IN pay_cursor LOOP
new_comm := (pay_record.salary+pay_record.comm) * .10;
if pay_record.comm > new_comm then
Update staff set salary = salary * 1.10
where current of pay_cursor;
end if;
countr := countr +1;
exit when countr > 25;
exit when (pay_cursor%ROWCOUNT >= 15) or (countr > 25);
END LOOP;
COMMIT work;
END;
/
To see how this works and what records it changes, perform the following select
before you execute the above script..
Select name, salary, comm, (salary + comm) * .10 from staff
where comm > (salary + comm) * .10;
If you get no rows, update id 60 in the staff table with a 5000 commission.CURSOR PROCESSING
Storing rows in a PL/SQL table using Cursor Processing
Task: Retrieve all employees id's and salaries who have a salary
of more than 10000. Store the qualified rows in a PL/SQL table. See PL47A.sql
DECLARE
TYPE id_table_type is TABLE OF NUMBER(3)
INDEX BY BINARY_INTEGER;
TYPE salary_table_type is TABLE OF NUMBER(11,2)
INDEX BY BINARY_INTEGER;
CNT BINARY_INTEGER :=0;
v_id staff.id%TYPE;
v_dept staff.dept%TYPE;
v_salary staff.salary%TYPE;
v_comm staff.comm%TYPE;
max_sal number(11,2);
id_table id_table_type;
salary_table salary_table_type;
CURSOR staff_cursor IS
select id,dept,salary
from staff
where salary > 10000;
BEGIN
FOR staff_record IN staff_cursor LOOP
CNT = CNT + 1;
id_table(CNT) := staff_record.id;
salary_table(CNT) := staff_record.salary;
END LOOP;
select max(salary) into max_sal from staff;
FOR J IN 1..CNT LOOP
IF salary_table(j) = max_sal
then insert into exception_table(message)
values(to_char(max_sal)||'MAX SALARY FOR'||to_char(id_table(j)));
END IF;
END LOOP;
COMMIT WORK;
END;
You can load your own single dimension tables using PL/SQL.
CURSOR PROCESSING
Passing values within the Declare cursor command
Task: Calculate the total pay for a specified department. Store the total
pay in a separate table for use later. See PL48.sql
SQL> ACCEPT p_dept_no PROMPT `ENTER DEPARTMENT NO'
DECLARE
V_dept staff.dept%TYPE := &NEWDEPT;
v_id staff.id%TYPE;
v_salary staff.salary%TYPE;
v_comm staff.comm%TYPE;
v_gross_pay NUMBER(9,2) :=0;
v_total_pay NUMBER(11,2) :=0;
....
CURSOR pay_cursor (temp_dept NUMBER) IS
select id, salary, nvl(comm,0)
from staff
where dept = temp_dept;
BEGIN
OPEN pay_cursor(v_dept);
LOOP
FETCH pay_cursor INTO v_id, v_salary,v_comm;
EXIT WHEN pay_cursor%NOTFOUND;
v_total_pay := v_total_pay + (v_salary + v_comm);
INSERT INTO temppay(deptno,dept_pay)
VALUES(v_dept,v_total_pay);
....
END LOOP;
CLOSE pay_cursor;
COMMIT WORK;
END;
NOTE:
 When opening the same cursor more than once, be sure to close it in between uses.
 Close the cursor immediately before reopening it to boost performance.
 After declaring an explicit cursor once, you can open it multiple times to retrieve different data, each time with different output.
LAB 9 - PL/SQL WORKSHOP
Task:
Create a PL/SQL block that computes the total compensation of all employees (salary + comm) in a specified department and provides salary increases based upon the following formula.
Salary Increase Minimum Pay Maximum Pay
0 0.00 10000.00
2 10000.01 20000.00
4 20000.01 & up
Accept a department number as input with a SQL*PLUS substitution parameter (optional).
Additionally, write a PL/SQL Block to include exception handling
for the following:
Accept as input an incorrect department number from SQL*PLUS.
Test for a `NOT FOUND' condition using a predefined ORACLE error name.
Put the error message `INCORRECT department NUMBER' and concatenate the department number to this message in the EXCEPTION_TABLE. Don't forget to convert the department number to a character field.
Calculate the grand total salary for the department and put it into a global variable called Grand_Total. Display the total monies on the screen using the PRINT command.
IMPORT AND EXPORT UTILITIES - Chapter 7
TOPIC OBJECTIVES
This section introduces the ORACLE utilities used for reorganizing tables and indexes. The utilities are called import and export. When you finish this section, you will be able to:
· Understand and execute the EXPORT utility to create an ORACLE
copy of objects within a database such as a table, index or privileges.
· Utilize the import utility to create a reorganized table or a new database depending upon the application
· Comprehend and execute SQL*LOADER to load a table from a sequential file
Database Population
Export and Import Utilities
The export utility is used to archive Oracle database information to host operating system files. In addition to the data in a table, table creation statements, grants, space definitions, etc. may be exported.
 Exporting is done to a 'filename.dmp' file.
The import utility loads Oracle databases from host operating system files created by the export utility.
 The export and import utilities do not require an ASCII to
EBCDIC conversion before execution.
 Data conversion is handled automatically by the utilities.
Other uses for the export utility include reorganization of an Oracle database, moving data between Oracle databases, converting databases from an older version of Oracle to the latest version of Oracle and moving data from one Oracle user to another Oracle user.
Import will only read files exported from Oracle databases with the same or earlier version number.
The compressed format of an export file cannot be edited and one must have resource or DBA authority before using the export utility.
Export Utility Command
What files do I want to copy?
The export utility command has the following format:
The utility execution then prompts for more information:
1. Enter array fetch buffer size (default 4096)
This is the amount of memory set aside for exported table rows.
2. Export file:
The suggested default file name is expdat.dmp.
3. An export mode prompt is next:
(1)E(ntire database), (2)U(sers), or (3)T(ables):
A user with DBA privilege may choose E, U, or T. A user with
only RESOURCE and CONNECT privileges can choose U or T.
The DBA modes can be: User - export table definitions, data,
clusters, indices, and first grants
Tables - export table definitions and data
Entire database - user mode plus all grants, views, synonyms and space definitions are exported.
4. Export Grants (Y/N): Y for E or U mode. Use 'N' to export only
table definitions and data.
5. Export table data (Yes/No): Yes
6. Compress extents (Y/N): Y
This will allow table reorganization. The actual compression does
not occur until execution of the Import Utility.
Import Utility Command
The import utility command has the following format:
This utility execution prompts for more information:
1. Import file:
The default filename is expdat.dmp (exported file).
2. Enter insert buffer size (default is 30720, minimum is 4096)
This allocates space in memory for the largest rows to be imported.
A buffer size of 40960 is recommended for full database import.
3. List contents of import file only (Y/N): N
Answering Y will display a list of the table names and space definitions to be imported.
4. Ignore create errors due to object existence (Y/N): Y
This question is asked when the contents of the import file is not listed. A Y to this question will import rows of tables even if those tables already exist. The imported rows will be added to the existing table and current rows will still exist. This may lead to duplicate rows if unique indexes don't exist to prevent inserting duplicate rows.
5. Import grants (Y:/N): Y
 Allows all grants to be imported.
6. Import table data (Y/N): Y
A response of N will only run the data definition statements in the import file.
7. Import of entire import file requested (Y/N): Y
Answering N to this question causes import to prompt for the user name and the specific tables to be imported.
COMMON COMMAND LINE PARAMETERS
Keyword Default Meaning
Userid Oracle command and password. If omitted, user is prompted.
Buffer <OS> Size of the buffer that will be used for storing the rows fetched
before they are written to the export file.
Compress Y A value of Y specifies that on import the initial extent size will be
set to a value that is equal to the current size of the segment. A
value of N will cause the current extent sizes to be retained.
The choice has to be made upon EXPORTing the file.
Consistent N A value of Y specifies that the entire export operation to be
performed in one read-only transaction. Export will attempt to
get a read-consistent image of all objects exported. A value of
N specifies only table-level consistency needs to be maintained.
Constraints Y A value of Y specifies that constraints are to be exported with
the table. A value of N causes constraints not to be exported.
Direct N A value of Y specifies that direct path be used for the export. A
value of N uses conventional path.
Feedback 0 This parameter is specified as an integer to request for a dot (.)
to be displayed when n rows are exported. Zero (0) specifies
that no data is to be displayed.
File expat Output filename default
Full N A value of Y specfies that a full database export will take place.
Grants Y A value of Y specifies that all the grants on objects to be
exported must also be preserved on import
Indexes Y A value of Y causes indexes to be exported.
Log NULL The name of the file to store all export messages. Default=screen.
Owners The names of the users for user-level export
Parfile The name of the file containing a list of export parameters
RecordLength <OS> The size of the output record
Rows Y A value of Y specifies that data is to be exported.
Statistics Estimate Analyze method to be used on import
Tables schema.table for table mode export.
SQL*LOADER
The Oracle SQL*LOADER utility program allows for the loading of data from flat files into the Oracle database.
SQL*LOADER was new as of Oracle Version 5.1.22 and will replace the Oracle Data Loader (ODL) utility in future versions of Oracle.
 SQL*LOADER also has many features that are similar to
IBM's DB2 Load Utility.
SQL*LOADER has the following capabilities:
1. Load data from multiple source data files of different file types.
2. Load fixed format, delimited format and variable length records.
3. Support a wide range of data types including DATE, BINARY, and PACKED DECIMAL.
4. Load multiple tables during one run with selected records loaded into each table.
5. Create one table row from multiple physical records.
6. Create multiple table rows from a single physical record.
7. Use existing DB2 Load Utility control files to load data
(including files produced by IBM's Data Extract Utility).
8. Generate unique sequential key values in specified table columns as data is being loaded.
Input to SQL*LOADER includes:
1. Data files
2. Control file that lists the names and format of the data files, the location and type of each data field in the data files and load control cards.
Output from SQL*LOADER includes:
1. A log file containing information about the results of the load operation.
2. A bad file containing records not loaded due to errors detected in the input data.
3. A discard file containing records rejected due to select conditions in the control file.
Invoking SQL*LOADER
Invoke the utility by typing:
where xx is your Oracle version.
Example: Control File Control Cards
LAB 11 - POPULATING TABLES THROUGH EXPORT/IMPORT
Lab A --- Exporting Data for Employees
Exercise:
 Data will be exported from the STAFF and ORG tables
 All of the data in both tables will be exported. Use an export file name of 'exp.dmp'.
 Grants, views, synonyms, space definitions, clusters, and indexes do not have to be exported.
Lab B --- Importing Data for Employees
Exercise:
 Data exported in Lab 1 will be imported for the 'staff' table.
 Rename the 'staff' table in the Employee tablespace to 'OLDstaff'. This will save the 'staff' table.
 Next, import from 'exp.dmp' all rows for the 'staff' table only. Import into table 'staff'.
LAB 11 - POPULATING TABLES THROUGH EXPORT/IMPORT
Lab C --- Loading Data using SQL*LOADER
Exercise:
 The IBM DXT Utility was used to extract data from a DB2 table called PRESIDENT.
 This data will be loaded into an Oracle table named PRES.
 Create the PRES table in the SYSTEM tablespace with these columns:
The DXT input file is named 'pres.ctl'.
 This file has the SQL*LOADER control cards and the data.
 Execute SQL*LOADER using 'pres.ctl' to load the PRES table.
|