PL SQL Student Guide v-3
PL SQL Student Guide v-3
PL SQL Student Guide v-3
nd
a
g
in
r
e
Oracle Database 10g:
neDevelop
i
g
n
PL/SQL Program
f E Units
o
te
u
t
i
t
Volume 3s Additional
y Practices
n
l
I
n
i
o
h
d
e
n
s
Ga gy u
d
n nolo
a
y
sit Tech
r
e
iv
U
cle
Ora
D17169GC21
Edition 2.1
December 2006
D48232
Authors
Tulika Srivastava
Glenn Stokol
Disclaimer
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Technical Contributors
and Reviewers
Chaitanya Koratamaddi
Dr. Christoph Burandt
Zarko Cesljas
Yanti Chang
Kathryn Cunningham
Burt Demchick
Laurent Dereac
Peter Driver
Bryan Roberts
Bryn Llewellyn
Nancy Greenberg
Craig Hollister
Thomas Hoogerwerf
Taj-Ul Islam
Inger Joergensen
Eric Lee
Malika Marghadi
Hildegard Mayr
Nagavalli Pataballa
Sunitha Patel
Srinivas Putrevu
Denis Raphaely
Helen Robertson
Grant Spencer
Glenn Stokol
Tone Thomas
Priya Vennapusa
Lex Van Der Werff
le
c
a
r
Graphic Designer
Satish Bettegowda
Nita Pavitran
Richard Wallis
Publisher
Sheryl Domingue
The information contained in this document is subject to change without notice. If you
find any problems in the document, please report them in writing to: Oracle University,
500 Oracle Parkway, Redwood Shores, California 94065 USA. This document is not
warranted to be error-free.
Restricted Rights Notice
If this documentation is delivered to the United States Government or anyone using
the documentation on behalf of the United States Government, the following notice is
applicable:
U.S. GOVERNMENT RIGHTS
The U.S. Governments rights to use, modify, reproduce, release, perform, display, or
disclose these training materials are restricted by the terms of the applicable Oracle
license agreement and/or the applicable U.S. Government contract.
nd
a
g
in
r
e
ne
Trademark Notice
gi
n
E
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
Editors
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Contents
Preface
I
Introduction
Lesson Objectives I-2
Course Objectives I-3
Course Agenda I-4
Human Resources (HR) Schema I-7
Creating a Modularized and Layered Subprogram Design I-8
Modularizing Development with PL/SQL Blocks I-9
Review of Anonymous Blocks I-10
Introduction to PL/SQL Procedures I-11
Introduction to PL/SQL Functions I-12
Introduction to PL/SQL Packages I-13
Introduction to PL/SQL Triggers I-14
PL/SQL Execution Environment I-15
PL/SQL Development Environments I-16
Coding PL/SQL in iSQL*Plus I-17
Coding PL/SQL in SQL*Plus I-18
Coding PL/SQL in Oracle JDeveloper I-19
Summary I-20
Practice I: Overview I-21
le
c
a
r
1
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
iii
gi
n
E
in
r
e
ne
nd
a
g
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
in
r
e
ne
nd
a
g
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
iv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Creating Packages
Objectives 3-2
PL/SQL Packages: Overview 3-3
Components of a PL/SQL Package 3-4
Visibility of Package Components 3-5
Developing PL/SQL Packages 3-6
Creating the Package Specification 3-7
Example of Package Specification: comm_pkg 3-8
Creating the Package Body 3-9
Example of Package Body: comm_pkg 3-10
Invoking Package Subprograms 3-11
Creating and Using Bodiless Packages 3-12
Removing Packages 3-13
Viewing Packages in the Data Dictionary 3-14
Guidelines for Writing Packages 3-15
Advantages of Using Packages 3-16
Summary 3-18
Practice 3: Overview 3-20
nd
a
g
in
r
e
ne
o
e
t
itu
t
s
4 Using More Package Concepts
n
ly
I
n
i
o
h
Objectives 4-2
nd use
Overloading Subprograms G
4-3a
gy
d
o
Overloading: Example
4-5
n
l
a hno
y
t
i
Overloading and
the
STANDARD
c Package 4-7
s T
r
e
e
Using Forward
iv Declarations 4-8
n
U Initialization Block 4-10
ePackage
l
c
Ora Using Package Functions in SQL and Restrictions 4-11
Package Function in SQL: Example 4-12
Persistent State of Packages 4-13
Persistent State of Package Variables: Example 4-14
Persistent State of a Package Cursor 4-15
Executing CURS_PKG 4-16
Using PL/SQL Tables of Records in Packages 4-17
PL/SQL Wrapper 4-18
Running the Wrapper 4-19
Results of Wrapping 4-20
Guidelines for Wrapping 4-21
Summary 4-22
Practice 4: Overview 4-23
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
le
c
a
r
in
r
e
ne
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
O
6
nd
a
g
vi
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
o
e
t
itu
t
s
In only
i
h
nd use
a
y
7 Design Considerations forG
PL/SQLgCode
d
o
n
l
a hno
Objectives 7-2
y
t
i
cand Exceptions 7-3
Standardizing
rsConstants
e
e
T
v
Standardizing
ni Exceptions 7-4
U
leStandardizing Exception Handling 7-5
c
a
Or Standardizing Constants 7-6
gi
n
E
vii
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Managing Dependencies
Objectives 8-2
Understanding Dependencies 8-3
Dependencies 8-4
Local Dependencies 8-5
A Scenario of Local Dependencies 8-7
Displaying Direct Dependencies by Using USER_DEPENDENCIES 8-8
Displaying Direct and Indirect Dependencies 8-9
Displaying Dependencies 8-10
Another Scenario of Local Dependencies 8-11
A Scenario of Local Naming Dependencies 8-12
Understanding Remote Dependencies 8-13
Concepts of Remote Dependencies 8-15
REMOTE_DEPENDENCIES_MODE Parameter 8-16
Remote Dependencies and Time Stamp Mode 8-17
Remote Procedure B Compiles at 8:00 a.m. 8-19
Local Procedure A Compiles at 9:00 a.m. 8-20
Execute Procedure A 8-21
Remote Procedure B Recompiled at 11:00 a.m. 8-22
Execute Procedure A 8-23
Signature Mode 8-24
Recompiling a PL/SQL Program Unit 8-25
Unsuccessful Recompilation 8-26
Successful Recompilation 8-27
Recompilation of Procedures 8-28
Packages and Dependencies 8-29
Summary 8-31
Practice 8: Overview 8-32
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
viii
gi
n
E
in
r
e
ne
nd
a
g
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
o
e
t
itu
t
DBMS_LOB.READ and DBMS_LOB.WRITE 9-23
s
In 9-24only
i
Initializing LOB Columns Added to a
Table
h
nd use
a
Populating LOB Columns 9-25
G gy
d
n
loin PL/SQL 9-26
Updating LOB by Using
DBMS_LOB
a
o
n
y
t ebycUsing
h SQL 9-27
Selecting CLOB
siValues
r
e
ivCLOB ValuesT by Using DBMS_LOB 9-28
Selecting
n
U CLOB Values in PL/SQL 9-29
leSelecting
DBMS_LOB Package 9-20
Ora
10 Creating Triggers
Objectives 10-2
Types of Triggers 10-3
Guidelines for Designing Triggers 10-4
Creating DML Triggers 10-5
Types of DML Triggers 10-6
Trigger Timing 10-7
Trigger-Firing Sequence 10-8
ix
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
o
e
t
itu
t
s
In only
i
h
11 Applications for Triggers
nd use
a
Objectives 11-2
G
y
nd nolog
Creating Database Triggersa11-3
h 11-4
ityStatements
Creating Triggers onrs
DDL
c
e
e
iv on SystemTEvents 11-5
Creating Triggers
n
U
LOGONle
and LOGOFF Triggers: Example 11-6
c
ra Statements 11-7
OCALL
gi
n
E
in
r
e
ne
nd
a
g
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
o
e
t
itu
t
s
Appendix A: Practice Solutions
In only
i
h
Appendix B: Table Descriptions and
ndData use
a
G gTriggers
y
Appendix C: Studies for Implementing
d
o
n
l
a hno
y
Appendix D: Review
of PL/SQL
t
i
rs Tec
e
Appendix E:
JDeveloper
v
ni
U
Appendix
le F: Using SQL Developer
c
a
Or Index
Additional Practices
Additional Practice: Solutions
Additional Practices: Table Descriptions and Data
xi
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
O
le
c
a
r
U
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Preface
nd
a
g
in
r
e
ne
O
le
c
a
r
U
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
O
le
c
a
r
U
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Profile
Before You Begin This Course
Before you begin this course, you should have thorough knowledge of SQL and iSQL*Plus, as
well as working experience in developing applications. Prerequisites are any of the following
Oracle University courses or combinations of courses:
Oracle Database 10g: Introduction to SQL
Oracle Database 10g: SQL Fundamentals I and Oracle Database 10g: SQL
Fundamentals II
Oracle Database 10g: SQL and PL/SQL Fundamentals
Oracle Database 10g: PL/SQL Fundamentals
How This Course Is Organized
Oracle Database 10g: Develop PL/SQL Program Units is an instructor-led course featuring
lectures and hands-on exercises. Online demonstrations and practice sessions reinforce the
concepts and skills that are introduced.
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
Preface-3
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Related Publications
Oracle Publications
Title
Oracle Database Application Developers Guide Fundamentals
(10g Release 1)
Oracle Database Application Developers Guide Large Objects
(10g Release 1)
PL/SQL Packages and Types Reference (10g Release 1)
PL/SQL Users Guide and Reference (10g Release 1)
Part Number
B10795-01
B10796-01
B10802-01
B10807-01
Additional Publications
System release bulletins
Installation and users guides
Read-me files
International Oracle Users Group (IOUG) articles
Oracle Magazine
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
Preface-4
gi
n
E
Typographic Conventions
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Element
Example
Bold
Bold italic
Brackets
Key names
Press [Enter].
Caps and
lowercase
Buttons,
check boxes,
triggers,
windows
in
r
e
ne
gi
n
E
f
o
e
ut
t
i
t
ns nly
I
i
o these keys one at a
h and erelease
Key sequences
Press
d
n
s
u
Ga gtime:
y
d
n nolo[Alt], [F], [D]
a
y
sit Tech
r
e
iv
n
U
Menu paths
Commas
cl
a
r
O
nd
a
g
Preface-5
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Object or Term
Example
Courier New,
case sensitive
Code output,
SQL and PL/SQL
code elements, Java
code elements,
directory names,
filenames,
passwords,
pathnames, URLs,
user input,
usernames
nd
a
g
in
r
e
ne
URLs: Go to http://www.oracle.com.
i
g
n
Usernames: Log on as scott. E
f
o
e
Graphics labels
Customer address (but
Oracle
t Payables)
u
t
i
t
(unless the term is a
ns nly
I
proper noun)
i
o
h
d
e
n
s
Emphasized words
changes
a not save
u to the database.
GDo
y
and phrases in print
g
d
o information, see Oracle7 Server SQL
n nForolfurther
a
publications,
titles
Language
Reference Manual.
y
itand ech
of books
s
r
T
Enter [email protected], where user_id is
ve variables
icourses,
User input: Enter 300.
Initial cap
Italic
U
e
l
c
Plus signs
Ora
Quotation
marks
Key combinations
Preface-6
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
Preface-7
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
O
le
c
a
r
U
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Additional
Practices
nd
a
g
in
r
e
ne
O
le
c
a
r
U
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
n
ngi
le
c
a
r
fE
o
ute
t
i
t
ns nly
I
i
o
h
d
e
n
s
Ga gy u
d
n nolo
a
y
sit Tech
r
e
niv
Part A
Entity Relationship Diagram
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Human Resources:
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Part A (continued)
Note: These exercises can be used for extra practice when discussing how to create
procedures.
1. In this exercise, create a program to add a new job into the JOBS table.
a. Create a stored procedure called NEW_JOB to enter a new order into the JOBS
table. The procedure should accept three parameters. The first and second
parameters supply a job ID and a job title. The third parameter supplies the
minimum salary. Use the maximum salary for the new job as twice the minimum
salary supplied for the job ID.
b. Invoke the procedure to add a new job with job ID 'SY_ANAL', job title
'System Analyst', and minimum salary of 6000.
c. Check whether a row was added and note the new job ID for use in the next
exercise. Commit the changes.
2. In this exercise, create a program to add a new row to the JOB_HISTORY table, for an
existing employee.
a. Create a stored procedure called ADD_JOB_HIST to add a new row into the
ndID
JOB_HISTORY table for an employee who is changing his job to the newajob
ing
('SY_ANAL') that you created in exercise 1b.
r
e
The procedure should provide two parameters, one for the employee
ne ID who is
i
g
changing the job, and the second for the new job ID. fRead
Enthe employee ID from
o
the EMPLOYEES table and insert it into the JOB_HISTORY
table. Make the hire
e
t
u
t
date of this employee as start date and todays
ti date
as end date for this row in the
s
y
n
l
I
JOB_HISTORY table.
i
on
h
d
e
Change the hire date of this employee
an y uinsthe EMPLOYEES table to todays date.
G
Update the job ID of this
g to the job ID passed as parameter (use the
d employee
o
n
l
a
o
'SY_ANAL' job
n equal to the minimum salary for that job ID +
ty ID)eand
hsalary
i
c
s
r
500.
e
T
v
i
n
Note:
Include
exception
handling to handle an attempt to insert a nonexistent
U
e
l
c employee.
Orab. Disable all triggers on the EMPLOYEES, JOBS, and JOB_HISTORY tables
before invoking the ADD_JOB_HIST procedure.
c. Execute the procedure with employee ID 106 and job ID 'SY_ANAL' as
parameters.
d. Query the JOB_HISTORY and EMPLOYEES tables to view your changes for
employee 106, and then commit the changes.
e. Re-enable the triggers on the EMPLOYEES, JOBS, and JOB_HISTORY tables.
3. In this exercise, create a program to update the minimum and maximum salaries for a
job in the JOBS table.
a. Create a stored procedure called UPD_JOBSAL to update the minimum and
maximum salaries for a specific job ID in the JOBS table. The procedure should
provide three parameters: the job ID, a new minimum salary, and a new
maximum salary. Add exception handling to account for an invalid job ID in the
JOBS table. Raise an exception if the maximum salary supplied is less than the
minimum salary, and provide a message that will be displayed if the row in the
JOBS table is locked.
Hint: The resource locked/busy error number is 54.
Oracle Database 10g: Develop PL/SQL Program Units AP-4
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Part A (continued)
b. Execute the UPD_JOBSAL procedure by using a job ID of 'SY_ANAL', a
minimum salary of 7000 and a maximum salary of 140.
Note: This should generate an exception message.
c. Disable triggers on the EMPLOYEES and JOBS tables.
d. Execute the UPD_JOBSAL procedure using a job ID of 'SY_ANAL', a
minimum salary of 7000, and a maximum salary of 14000.
e. Query the JOBS table to view your changes, and then commit the changes.
f. Enable the triggers on the EMPLOYEES and JOBS tables.
4. In this exercise, create a procedure to monitor whether employees have exceeded their
average salaries for their job type.
a. Disable the SECURE_EMPLOYEES trigger.
b. In the EMPLOYEES table, add an EXCEED_AVGSAL column to store up to three
characters and a default value of NO. Use a check constraint to allow the values
YES or NO.
c. Write a stored procedure called CHECK_AVGSAL which checks whether eachd
an
employees salary exceeds the average salary for the JOB_ID. The average
g
inIf the
r
salary for a job is calculated from the information in the JOBS table.
e
netheir
i
employees salary exceeds the average for their job, then update
g
Eanvalue of YES;
EXCEED_AVGSAL column in the EMPLOYEES tablef to
o
otherwise, set the value to NO. Use a cursor touselect
te the employees rows using
t
i
t
the FOR UPDATE option in the query. n
Add
s exception
y handling to account for a
l
I
n
i
o
record being locked.
h
d
e
n
s
Hint: The resource locked/busy
number
is 54. Write and use a local
a error
u
G
y
g
d
function called GET_JOB_AVGSAL
n nolo to determine the average salary for a job ID
a
y
specified as asparameter.
it ech
r
e
d. Executeivthe CHECK_AVGSAL
procedure. Then, to view the results of your
T
n
U
modifications,
write a query to display the employees ID, job, the average salary
efor
l
c
the
job,
the
employees salary and the exceed_avgsal indicator column
Ora for employees whose salaries exceed the average for their job, and finally
commit the changes.
Note: These exercises can be used for extra practice when discussing how to create
functions.
5. Create a subprogram to retrieve the number of years of service for a specific employee.
a. Create a stored function called GET_YEARS_SERVICE to retrieve the total
number of years of service for a specific employee. The function should accept
the employee ID as a parameter and return the number of years of service. Add
error handling to account for an invalid employee ID.
b. Invoke the GET_YEARS_SERVICE function in a call to
DBMS_OUTPUT.PUT_LINE for an employee with ID 999.
c. Display the number of years of service for employee 106 with
DBMS_OUTPUT.PUT_LINE invoking the GET_YEARS_SERVICE function.
d. Query the JOB_HISTORY and EMPLOYEES tables for the specified employee to
verify that the modifications are accurate. The values represented in the results
on this page may differ from those you get when you run these queries.
Oracle Database 10g: Develop PL/SQL Program Units AP-5
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Part A (continued)
6. In this exercise, create a program to retrieve the number of different jobs that an
employee worked on during his or her service.
a. Create a stored function called GET_JOB_COUNT to retrieve the total number of
different jobs on which an employee worked.
The function should accept the employee ID in a parameter, and return the
number of different jobs that the employee worked on until now, including the
present job. Add exception handling to account for an invalid employee ID.
Hint: Use the distinct job IDs from the JOB_HISTORY table, and exclude the
current job ID, if it is one of the job IDs on which the employee has already
worked. Write a UNION of two queries and count the rows retrieved into a
PL/SQL table. Use a FETCH with BULK COLLECT INTO to obtain the unique
jobs for the employee.
b. Invoke the function for the employee with the ID of 176.
Note: These exercises can be used for extra practice when discussing how to create
packages.
nd
a
7. Create a package called EMPJOB_PKG that contains your NEW_JOB,
ng
i
r
e
ADD_JOB_HIST, UPD_JOBSAL procedures, as well as your
ne
GET_YEARS_SERVICE and GET_JOB_COUNT functions. ngi
f E constructs as public.
a. Create the package specification with all the subprogram
o
e package specification.
Move any subprogram local-defined types into
utthe
t
i
t
b. Create the package body with the subprogram
remember to
y
ns implementation;
l
I
n
i
o
h
remove, from the subprogram n
implementations,
d
e any types that you moved into
s
a
u
the package specification.G
gy procedure to create a new job with the
d
o
n
l
c. Invoke your EMPJOB_PKG.NEW_JOB
a hno
y
t
i
ID PR_MAN,
the
job
c Public Relations Manager, and the salary
s Ttitle
r
e
e
v
6,250.
i
n
U
d. le
Invoke your EMPJOB_PKG.ADD_JOB_HIST procedure to modify the job of
c
a
employee ID 110 to job ID PR_MAN.
Or Note:
You need to disable the UPDATE_JOB_HISTORY trigger before you
execute the ADD_JOB_HIST procedure, and re-enable the trigger after you have
executed the procedure.
e. Query the JOBS, JOB_HISTORY, and EMPLOYEES tables to verify the results.
Note: These exercises can be used for extra practice when discussing how to create database
triggers.
8. In this exercise, create a trigger to ensure that the minimum and maximum salaries of a
job are never modified such that the salary of an existing employee with that job ID is
out of the new range specified for the job.
a. Create a trigger called CHECK_SAL_RANGE that is fired before every row that is
updated in the MIN_SALARY and MAX_SALARY columns in the JOBS table.
For any minimum or maximum salary value that is changed, check whether the
salary of any existing employee with that job ID in the EMPLOYEES table falls
within the new range of salaries specified for this job ID. Include exception
handling to cover a salary range change that affects the record of any existing
employee.
Oracle Database 10g: Develop PL/SQL Program Units AP-6
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Part A (continued)
b. Test the trigger using the SY_ANAL job, setting the new minimum salary to
5,000, and the new maximum salary to 7,000. Before you make the change,
write a query to display the current salary range for the SY_ANAL job ID, and
another query to display the employee ID, last name, and salary for the same job
ID. After the update, query the change (if any) to the JOBS table for the specified
job ID.
c. Using the SY_ANAL job, set the new minimum salary to 7,000, and the new
maximum salary to 18,000. Explain the results.
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Part B
Entity Relationship Diagram
TITLE
for
RESERVATION
#* reservation date
the subject
of
set up for
#* ID
* title
* description
o rating
o category
o release date
available as
nd
a
g
a copy
in
r
e
ne
gi
n
E
f
o
TITLE_COPY
e
ut #* ID
t
i
t
ns nly * status
I
i
o
h
d
e
n
s
Ga gy u
d
the subject of
n nolo
a
y
responsible
sit Tech
for iver
n
U
e
cl MEMBER
made against
a
r
O
#* ID
* last name
o first name
o address
o city
o phone
* join date
responsible
for
created
for
RENTAL
#* book date
o act ret date
o exp ret date
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Part B (continued)
In this case study, you create a package named VIDEO_PKG that contains procedures and
functions for a video store application. This application enables customers to become a
member of the video store. Any member can rent movies, return rented movies, and reserve
movies. Additionally, you create a trigger to ensure that any data in the video tables is
modified only during business hours.
Create the package by using iSQL*Plus and use the DBMS_OUTPUT Oracle-supplied
package to display messages.
The video store database contains the following tables: TITLE, TITLE_COPY, RENTAL,
RESERVATION, and MEMBER. The entity relationship diagram is shown on the previous
page.
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Part B (continued)
1. Load and execute the E:\labs\PLPU\labs\buildvid1.sql script to create all
the required tables and sequences that are needed for this exercise.
2. Load and execute the E:\labs\PLPU\labs\buildvid2.sql script to populate
all the tables created through the buildvid1.sql script.
3. Create a package named VIDEO_PKG with the following procedures and functions:
a. NEW_MEMBER: A public procedure that adds a new member to the MEMBER
table. For the member ID number, use the sequence MEMBER_ID_SEQ; for the
join date, use SYSDATE. Pass all other values to be inserted into a new row as
parameters.
b. NEW_RENTAL: An overloaded public function to record a new rental. Pass the
title ID number for the video that a customer wants to rent, and either the
customers last name or his member ID number into the function. The function
should return the due date for the video. Due dates are three days from the date
the video is rented. If the status for a movie requested is listed as AVAILABLE in
the TITLE_COPY table for one copy of this title, then update this TITLE_COPY
nd
a
table and set the status to RENTED. If there is no copy available, the function
ng
iidentifying
r
must return NULL. Then, insert a new record into the RENTAL table
e
ne ID number,
i
the booked date as todays date, the copy ID number, the member
g
En of multiple
the title ID number, and the expected return date. Befaware
o
customers with the same last name. In this case,
tehave the function return NULL,
u
t
i
t
and display a list of the customers names
s that match
y and their ID numbers.
n
l
I
n
i
c. RETURN_MOVIE: A public procedure
o the status of a video
h thateupdates
d
n
s
(available, rented, or damaged)
a andysetsu the return date. Pass the title ID, the
G
d
procedure.
Check whether there are reservations
copy ID, and the status
og
n to this
l
a
o
n
y
for that title and
ahmessage if it is reserved. Update the RENTAL table
it display
c
s
r
e
e
T date to todays date. Update the status in the
and setithe
v actual return
n
table based on the status parameter passed into the procedure.
U
eTITLE_COPY
l
c
d.
RESERVE_MOVIE:
A private procedure that executes only if all the video
Ora copies requested in the NEW_RENTAL procedure have a status of RENTED. Pass
the member ID number and the title ID number to this procedure. Insert a new
record into the RESERVATION table and record the reservation date, member
ID number, and title ID number. Print a message indicating that a movie is
reserved and its expected date of return.
e. EXCEPTION_HANDLER: A private procedure that is called from the exception
handler of the public programs. Pass the SQLCODE number to this procedure,
and the name of the program (as a text string) where the error occurred. Use
RAISE_APPLICATION_ERROR to raise a customized error. Start with a
unique key violation (-1) and foreign key violation (-2292). Allow the
exception handler to raise a generic error for any other errors.
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Part B (continued)
4. Use the following scripts located in the E:\labs\PLPU\soln directory to test your
routines:
a. Add two members using sol_apb_04_a_new_members.sql.
b. Add new video rentals using sol_apb_04_b_new_rentals.sql.
c. Return movies using the sol_apb_04_c_return_movie.sql script.
5. The business hours for the video store are 8:00 a.m. to 10:00 p.m., Sunday through
Friday, and 8:00 a.m. to 12:00 a.m. on Saturday. To ensure that the tables can be
modified only during these hours, create a stored procedure that is called by triggers on
the tables.
a. Create a stored procedure called TIME_CHECK that checks the current time
against business hours. If the current time is not within business hours, use the
RAISE_APPLICATION_ERROR procedure to give an appropriate message.
b. Create a trigger on each of the five tables. Fire the trigger before data is inserted,
updated, and deleted from the tables. Call your TIME_CHECK procedure from
each of these triggers.
d
a
g
n
i
er
n
ngi
le
c
a
r
fE
o
ute
t
i
t
ns nly
I
i
o
h
d
e
n
s
Ga gy u
d
n nolo
a
y
sit Tech
r
e
niv
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
O
le
c
a
r
U
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
_________
Additional
Practice:
Solutions
_________
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
1. In this exercise, create a program to add a new job into the JOBS table.
a. Create a stored procedure called NEW_JOB to enter a new order into the JOBS table.
The procedure should accept three parameters. The first and second parameters supply a
job ID and a job title. The third parameter supplies the minimum salary. Use the
maximum salary for the new job as twice the minimum salary supplied for the job ID.
CREATE OR REPLACE PROCEDURE new_job(
jobid IN jobs.job_id%TYPE,
title IN jobs.job_title%TYPE,
minsal IN jobs.min_salary%TYPE) IS
maxsal jobs.max_salary%TYPE := 2 * minsal;
BEGIN
INSERT INTO jobs(job_id, job_title, min_salary, max_salary)
VALUES (jobid, title, minsal, maxsal);
DBMS_OUTPUT.PUT_LINE ('New row added to JOBS table:');
DBMS_OUTPUT.PUT_LINE (jobid || ' ' || title ||' '||
minsal || ' ' || maxsal);
END new_job;
/
SHOW ERRORS
nd
a
g
in
r
e
ne
gi
n
E
f
o
e
ut
t
i
Procedure created.
t
ns nly
I
i
o
h
No errors.
d
e
n
s
Ga gy u
d
na newnjob
b. Invoke the procedure to a
add
lowith job ID 'SY_ANAL', job title
o
y
h
'System Analyst',
salary 6,000.
sit Tandecminimum
r
e
iv ON
SET SERVEROUTPUT
n
EXECUTE lnew_job
e U ('SY_ANAL', 'System Analyst', 6000)
c
Ora
New row added to JOBS table:
SY_ANAL System Analyst 6000 12000
PL/SQL procedure successfully completed.
c. Verify that a row was added, and note the new job ID for use in the next exercise.
Commit the changes.
SELECT *
FROM
jobs
WHERE job_id = 'SY_ANAL';
COMMIT;
Commit complete.
Oracle Database 10g: Develop PL/SQL Program Units APS-2
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
2. In this exercise, create a program to add a new row to the JOB_HISTORY table for an
existing employee.
a. Create a stored procedure called ADD_JOB_HIST to add a new row into the
JOB_HISTORY table for an employee who is changing his job to the new job ID
('SY_ANAL') that you created in exercise1b.
The procedure should provide two parameters: one for the employee ID who is changing
the job, and the second for the new job ID. Read the employee ID from the EMPLOYEES
table and insert it into the JOB_HISTORY table. Make the hire date of this employee as
the start date and todays date as the end date for this row in the JOB_HISTORY table.
Change the hire date of this employee in the EMPLOYEES table to todays date. Update
the job ID of this employee to the job ID passed as parameter (use the 'SY_ANAL' job
ID) and salary equal to the minimum salary for that job ID plus 500.
nd
a
g
in
r
e
Note: Include exception handling to handle an attempt to insert a nonexistent
ne employee.
i
g
En
CREATE OR REPLACE PROCEDURE add_job_hist(
f
o
emp_id
IN employees.employee_id%TYPE,
ute
t
new_jobid IN jobs.job_id%TYPE) IS
i
t
BEGIN
ns nly
I
i
o
h
INSERT INTO job_history
d
e
n
s
SELECT employee_id, hire_date,
u job_id, department_id
Ga gSYSDATE,
y
FROM
employees
d
nemp_id;
lo
a
o
WHERE employee_id
=
n
y
h
UPDATE employeesrsit
c
e
e
T
SET hire_date
= SYSDATE,
iv = new_jobid,
n
job_id
U
esalary
l
= (SELECT min_salary + 500
c
FROM
jobs
Ora
WHERE job_id = new_jobid)
WHERE employee_id = emp_id;
DBMS_OUTPUT.PUT_LINE ('Added employee ' || emp_id ||
' details to the JOB_HISTORY table');
DBMS_OUTPUT.PUT_LINE ('Updated current job of employee ' ||
emp_id|| ' to '|| new_jobid);
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR (-20001, 'Employee does not exist!');
END add_job_hist;
/
SHOW ERRORS
Procedure created.
No errors.
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
b. Disable all triggers on the EMPLOYEES, JOBS, and JOB_HISTORY tables before
invoking the ADD_JOB_HIST procedure.
ALTER TABLE employees DISABLE ALL TRIGGERS;
ALTER TABLE jobs DISABLE ALL TRIGGERS;
ALTER TABLE job_history DISABLE ALL TRIGGERS;
Table altered.
Table altered.
Table altered.
c. Execute the procedure with employee ID 106 and job ID 'SY_ANAL' as parameters.
nd
a
g
o
e
t
itu
t
s
n
ly
I
n
i
o
h
SELECT *
FROM
job_history
nd use
WHERE employee_id = 106;
a
G gy
d
n
lo
o
SELECT job_id, salary aFROM nemployees
y
WHERE employee_idrs=it106; ech
T
ve
i
n
COMMIT;
eU
l
c
Ora
in
r
e
ne
gi
n
E
d. Query the JOB_HISTORY and EMPLOYEES tables to view your changes for employee
106, and then commit the changes.
Commit complete.
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
3. In this exercise, create a program to update the minimum and maximum salaries for a job in
the JOBS table.
a. Create a stored procedure called UPD_JOBSAL to update the minimum and maximum
salaries for a specific job ID in the JOBS table. The procedure should provide three
parameters: the job ID, a new minimum salary, and a new maximum salary. Add
exception handling to account for an invalid job ID in the JOBS table. Raise an exception
if the maximum salary supplied is less than the minimum salary. Provide a message that
will be displayed if the row in the JOBS table is locked.
Hint: The resource locked/busy error number is 54.
CREATE OR REPLACE PROCEDURE upd_jobsal(
jobid
IN jobs.job_id%type,
new_minsal IN jobs.min_salary%type,
new_maxsal IN jobs.max_salary%type) IS
dummy
PLS_INTEGER;
e_resource_busy EXCEPTION;
sal_error
EXCEPTION;
PRAGMA
EXCEPTION_INIT (e_resource_busy , -54);
BEGIN
IF (new_maxsal < new_minsal) THEN
RAISE sal_error;
END IF;
SELECT 1 INTO dummy
FROM jobs
WHERE job_id = jobid
FOR UPDATE OF min_salary NOWAIT;
UPDATE jobs
SET min_salary = new_minsal,
max_salary = new_maxsal
WHERE job_id = jobid;
EXCEPTION
WHEN e_resource_busy THEN
RAISE_APPLICATION_ERROR (-20001,
'Job information is currently locked, try later.');
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20001, 'This job ID does not exist');
WHEN sal_error THEN
RAISE_APPLICATION_ERROR(-20001,
'Data error: Max salary should be more than min salary');
END upd_jobsal;
/
SHOW ERRORS
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Procedure created.
No errors.
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
gi
n
E
f
o
e
ut
t
Table altered.
i
t
ns nly
I
i
h a jobeIDoof 'SY_ANAL', a minimum
d
d. Execute the UPD_JOBSAL procedurenusing
a of y14000.
us
salary of 7000, and a maximumG
salary
d olog
n
a
EXECUTE upd_jobsal('SY_ANAL',
ity echn7000, 14000)
s
r
T
PL/SQL procedure
completed.
ivesuccessfully
n
U
cle the JOBS table to view your changes, and then commit the changes.
e.raQuery
O
Table altered.
SELECT *
FROM jobs
WHERE job_id = 'SY_ANAL';
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
4. In this exercise, create a procedure to monitor whether employees have exceeded their
average salaries for their job type.
a. Disable the SECURE_EMPLOYEES trigger.
ALTER TRIGGER secure_employees DISABLE;
Trigger altered.
nd
a
g
in
r
e
ne
Table altered.
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
c. Write a stored procedure called CHECK_AVGSAL that checks whether each employees
salary exceeds the average salary for the JOB_ID. The average salary for a job is
calculated from information in the JOBS table. If the employees salary exceeds the
average for his or her job, then update his or her EXCEED_AVGSAL column in the
EMPLOYEES table to a value of YES; otherwise, set the value to NO. Use a cursor to
select the employees rows using the FOR UPDATE option in the query. Add exception
handling to account for a record being locked.
Hint: The resource locked/busy error number is 54. Write and use a local function
called GET_JOB_AVGSAL to determine the average salary for a job ID specified as a
parameter.
le
c
a
r
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
gi
n
E
f
o
e
ut
t
i
t
ns nly
I
i
o
h
d
e
n
s
Ga gy u
d
n nolo
a
y
Procedure created. it
s Tech
r
e
v
No errors. Uni
le
c
a
Od.r Execute the CHECK_AVGSAL procedure. Then, to view the results of your modifications,
write a query to display the employees ID, job, the average salary for the job, the
employees salary, and the exceed_avgsal indicator column for employees whose
salaries exceed the average for their job, and finally commit the changes.
EXECUTE check_avgsal
SELECT e.employee_id, e.job_id, (j.max_salary-j.min_salary/2) job_avgsal,
e.salary, e.exceed_avgsal avg_exceeded
FROM
employees e, jobs j
WHERE e.job_id = j.job_id
and e.exceed_avgsal = 'YES';
COMMIT;
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
o
e
t
itu
t
Commit complete.
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
iv
n
eU
l
c
Ora
31 rows selected.
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
5. Create a subprogram to retrieve the number of years of service for a specific employee.
a. Create a stored function called GET_YEARS_SERVICE to retrieve the total number of
years of service for a specific employee. The function should accept the employee ID as a
parameter and return the number of years of service. Add error handling to account for an
invalid employee ID.
CREATE OR REPLACE FUNCTION get_years_service(
emp_id IN employees.employee_id%TYPE) RETURN NUMBER IS
CURSOR jobh_csr IS
SELECT MONTHS_BETWEEN(end_date, start_date)/12) years_in_job
FROM
job_history
WHERE employee_id = emp_id;
years_service NUMBER(2) := 0;
years_in_job NUMBER(2) := 0;
BEGIN
FOR jobh_rec IN jobh_csr
LOOP
EXIT WHEN jobh_csr%NOTFOUND;
years_service := years_service + job_rec.years_in_job;
END LOOP;
SELECT MONTHS_BETWEEN(SYSDATE, hire_date)/12 INTO years_in_job
FROM
employees
WHERE employee_id = emp_id;
years_service := years_service + years_in_job;
RETURN ROUND(years_service);
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20348,
'Employee with ID '|| emp_id ||' does not exist.');
END get_years_service;
/
SHOW ERRORS
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Function created.
No errors.
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
d. Query the JOB_HISTORY and EMPLOYEES tables for the specified employee to verify
that the modifications are accurate.
Note: The values represented in the results on this page may differ from those you get
when you run these queries.
nd
a
g
gi
n
E
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
in
r
e
ne
11 rows selected.
SELECT job_id, MONTHS_BETWEEN(SYSDATE, hire_date)/12 duration
FROM
employees
WHERE employee_id = 106;
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
6. In this exercise, create a program to retrieve the number of different jobs that an employee
worked on during his or her service.
a. Create a stored function called GET_JOB_COUNT to retrieve the total number of
different jobs on which an employee worked.
The function should accept the employee ID in a parameter, and return the number of
different jobs that the employee worked on until now, including the present job. Add
exception handling to account for an invalid employee ID.
Hint: Use the distinct job IDs from the JOB_HISTORY table, and exclude the current
job ID, if it is one of the job IDs on which the employee has already worked. Write a
UNION of two queries and count the rows retrieved into a PL/SQL table. Use a FETCH
with BULK COLLECT INTO to obtain the unique jobs for the employee.
CREATE OR REPLACE FUNCTION get_job_count(
emp_id IN employees.employee_id%TYPE) RETURN NUMBER IS
TYPE jobs_tabtype IS TABLE OF jobs.job_id%type;
jobtab jobs_tabtype;
CURSOR empjob_csr IS
SELECT job_id
FROM job_history
WHERE employee_id = emp_id
UNION
SELECT job_id
FROM employees
WHERE employee_id = emp_id;
BEGIN
OPEN empjob_csr;
FETCH empjob_csr BULK COLLECT INTO jobtab;
CLOSE empjob_csr;
RETURN jobtab.count;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20348,
'Employee with ID '|| emp_id ||' does not exist!');
END get_job_count;
/
SHOW ERRORS
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
in
r
e
ne
nd
a
g
gi
n
E
Function created.
No errors.
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
7. Create a package called EMPJOB_PKG that contains your NEW_JOB, ADD_JOB_HIST, and
UPD_JOBSAL procedures, as well as your GET_YEARS_SERVICE and GET_JOB_COUNT
functions.
a. Create the package specification with all the subprogram constructs public. Move any
subprogram local-defined types into the package specification.
CREATE OR REPLACE PACKAGE empjob_pkg IS
TYPE jobs_tabtype IS TABLE OF jobs.job_id%type;
PROCEDURE add_job_hist(
emp_id IN employees.employee_id%TYPE,
new_jobid IN jobs.job_id%TYPE);
FUNCTION get_job_count(
emp_id IN employees.employee_id%TYPE) RETURN NUMBER;
FUNCTION get_years_service(
emp_id IN employees.employee_id%TYPE) RETURN NUMBER;
PROCEDURE new_job(
jobid IN jobs.job_id%TYPE,
title IN jobs.job_title%TYPE,
minsal IN jobs.min_salary%TYPE);
PROCEDURE upd_jobsal(
jobid IN jobs.job_id%type,
new_minsal IN jobs.min_salary%type,
new_maxsal IN jobs.max_salary%type);
END empjob_pkg;
/
SHOW ERRORS
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
iv
Package created.
n
eU
l
c
No errors.
Ora
in
r
e
ne
nd
a
g
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
b. Create the package body with the subprogram implementation; remember to remove
(from the subprogram implementations) any types that you moved into the package
specification.
CREATE OR REPLACE PACKAGE BODY empjob_pkg IS
PROCEDURE add_job_hist(
emp_id IN employees.employee_id%TYPE,
new_jobid IN jobs.job_id%TYPE) IS
BEGIN
INSERT INTO job_history
SELECT employee_id, hire_date, SYSDATE, job_id, department_id
FROM employees
WHERE employee_id = emp_id;
UPDATE employees
SET hire_date = SYSDATE,
job_id = new_jobid,
salary = (SELECT min_salary + 500
FROM jobs
WHERE job_id = new_jobid)
WHERE employee_id = emp_id;
DBMS_OUTPUT.PUT_LINE ('Added employee ' || emp_id ||
' details to the JOB_HISTORY table');
DBMS_OUTPUT.PUT_LINE ('Updated current job of employee ' ||
emp_id|| ' to '|| new_jobid);
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR (-20001, 'Employee does not exist!');
END add_job_hist;
nd
a
g
in
r
e
ne
gi
n
E
f
o
e
ut
t
i
t
ns nly
I
i
o
h
d
e
n
s
Ga gy u
d
n nolo
a
y
sit Tech
r
e
FUNCTION get_job_count(
iv
emp_id U
INn employees.employee_id%TYPE) RETURN NUMBER
le jobs_tabtype;
jobtab
c
a
empjob_csr IS
OrCURSOR
SELECT job_id
IS
FROM job_history
WHERE employee_id = emp_id
UNION
SELECT job_id
FROM employees
WHERE employee_id = emp_id;
BEGIN
OPEN empjob_csr;
FETCH empjob_csr BULK COLLECT INTO jobtab;
CLOSE empjob_csr;
RETURN jobtab.count;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20348,
'Employee with ID '|| emp_id ||' does not exist!');
END get_job_count;
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
f
o
e
ut
t
i
t
ns nly
I
i
o
h
d
e
PROCEDURE new_job(
n
s
Ga gy u
jobid IN jobs.job_id%TYPE,
d
n nolo
title IN jobs.job_title%TYPE,
a
y
minsal IN jobs.min_salary%TYPE)
sit Tech := 2IS* minsal;
r
maxsal jobs.max_salary%TYPE
e
iv
n
BEGIN
INSERT
e UINTO jobs(job_id, job_title, min_salary,
l
c
a
(jobid, title, minsal, maxsal);
OrVALUES
gi
n
E
max_salary)
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
Trigger altered.
gi
n
E
e. Query the JOBS, JOB_HISTORY, and EMPLOYEES tables to verify the results.
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
le
c
a
r
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
8. In this exercise, create a trigger to ensure that the minimum and maximum salaries of a job
are never modified such that the salary of an existing employee with that job ID is outside the
new range specified for the job.
a. Create a trigger called CHECK_SAL_RANGE that is fired before every row that is
updated in the MIN_SALARY and MAX_SALARY columns in the JOBS table. For any
minimum or maximum salary value that is changed, check whether the salary of any
existing employee with that job ID in the EMPLOYEES table falls within the new range of
salaries specified for this job ID. Include exception handling to cover a salary range
change that affects the record of any existing employee.
CREATE OR REPLACE TRIGGER check_sal_range
BEFORE UPDATE OF min_salary, max_salary ON jobs
FOR EACH ROW
DECLARE
minsal employees.salary%TYPE;
maxsal employees.salary%TYPE;
e_invalid_salrange EXCEPTION;
BEGIN
SELECT MIN(salary), MAX(salary) INTO minsal, maxsal
FROM employees
WHERE job_id = :NEW.job_id;
IF (minsal < :NEW.min_salary) OR (maxsal > :NEW.max_salary) THEN
RAISE e_invalid_salrange;
END IF;
EXCEPTION
WHEN e_invalid_salrange THEN
RAISE_APPLICATION_ERROR(-20550,
'Employees exist whose salary is out of the specified range. '||
'Therefore the specified salary range cannot be updated.');
END check_sal_range;
/
SHOW ERRORS
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Trigger created.
No errors.
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
o
e
t
itu
t
s
In only
i
h
nd use
1 row updated.
a
G gy
d
n
lo
a
SELECT * FROM jobs
o
n
y
WHERE job_id = 'SY_ANAL';
sit Tech
r
e
iv
n
eU
l
c
Ora
UPDATE jobs
SET min_salary = 5000, max_salary = 7000
WHERE job_id = 'SY_ANAL';
gi
n
E
c. Using the job SY_ANAL, set the new minimum salary to 7000 and the new maximum salary
to 18000. Explain the results.
UPDATE jobs
SET min_salary = 7000, max_salary = 18000
WHERE job_id = 'SY_ANAL';
UPDATE jobs
*
ERROR at line 1:
ORA-20550: Employees exist whose salary is out of the specified range.
Therefore the specified salary range cannot be updated.
ORA-06512: at "ORA1.CHECK_SAL_RANGE", line 14
ORA-04088: error during execution of trigger 'ORA1.CHECK_SAL_RANGE'
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
TITLE
for
RESERVATION
#* reservation date
the subject
of
set up
#* ID
* title
* description
o rating
o category
o release date
available as
nd
a
g
in
r
e
ne
gi
n
E
TITLE_COP
Y
#* ID
f
o
e
ut
t
i
t
ns nly the subject
I
i
o
h
d
e
n
s
f
a yu
responsible
G
g
d
for
n nolo
a
y
sit Tech
made against
MEMBERver
i
n
#* ID U
*le
last name
c
RENTAL
a
responsible
r
O o first name
#* book date
for
o address
o city
o phone
* join date
created
for
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Part B (continued)
In this case study, create a package named VIDEO_PKG that contains procedures and functions
for a video store application. This application enables customers to become a member of the
video store. Any member can rent movies, return rented movies, and reserve movies.
Additionally, create a trigger to ensure that any data in the video tables is modified only during
business hours.
Create the package by using iSQL*Plus and use the DBMS_OUTPUT Oracle-supplied package to
display messages.
The video store database contains the following tables: TITLE, TITLE_COPY, RENTAL,
RESERVATION, and MEMBER. The entity relationship diagram is shown on the previous page.
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
TABLE
TABLE
TABLE
TABLE
TABLE
nd
a
g
in
r
e
ne
gi
n
E
f
o
e
ut
t
i
t
CREATE TABLE MEMBER
ns nly
I
i
omember_id_pk
(member_id NUMBER (10)
CONSTRAINT
h
d
e
n
s
, last_name VARCHAR2(25)
a yu
GNOT
CONSTRAINT member_last_nn
g
d
n noloNULL
, first_name VARCHAR2(25)
a
ity ech
, address
VARCHAR2(100)
s
r
T
, city
VARCHAR2(30)
ve
i
n
, phone U VARCHAR2(25)
le DATE DEFAULT SYSDATE
, join_date
c
a
OrCONSTRAINT join_date_nn NOT NULL)
/
PROMPT Please wait while tables are created....
PRIMARY KEY
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
eU
l
c
PROMPT
ra Tables
O
DROP SEQUENCE
created.
title_id_seq;
DROP SEQUENCE member_id_seq;
PROMPT Creating Sequences...
CREATE SEQUENCE member_id_seq
START WITH 101
NOCACHE
CREATE SEQUENCE title_id_seq
START WITH 92
NOCACHE
/
PROMPT Sequences created.
PROMPT Run buildvid2.sql now to populate the above tables.
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
COMMIT;
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
COMMIT;
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
INTO
title_copy
title_copy
title_copy
title_copy
title_copy
title_copy
title_copy
title_copy
title_copy
title_copy
title_copy
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
(1,92,
(1,93,
(2,93,
(1,94,
(1,95,
(2,95,
(3,95,
(1,96,
(1,97,
(1,98,
(2,98,
'AVAILABLE');
'AVAILABLE');
'RENTED');
'AVAILABLE');
'AVAILABLE');
'AVAILABLE');
'RENTED');
'AVAILABLE');
'AVAILABLE');
'RENTED');
'AVAILABLE');
COMMIT;
Oracle Database 10g: Develop PL/SQL Program Units APS-27
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
COMMIT;
INSERT
INSERT
INSERT
INSERT
INSERT
INTO
INTO
INTO
INTO
INTO
rental
rental
rental
rental
rental
VALUES
VALUES
VALUES
VALUES
VALUES
(sysdate-1,
(sysdate-2,
(sysdate-3,
(sysdate-4,
(sysdate-3,
2,
3,
1,
1,
1,
101,
102,
101,
106,
101,
93,
95,
98,
97,
92,
null, sysdate+1);
null, sysdate);
null, sysdate-1);
sysdate-2, sysdate-2);
sysdate-2, sysdate-1);
COMMIT;
PROMPT ** Tables built and data loaded **
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
3. Create a package named VIDEO_PKG with the following procedures and functions:
a. NEW_MEMBER: A public procedure that adds a new member to the MEMBER table. For
the member ID number, use the sequence MEMBER_ID_SEQ. For the join date, use
SYSDATE. Pass all other values to be inserted into a new row as parameters.
b. NEW_RENTAL: An overloaded public function to record a new rental. Pass the title ID
number for the video that a customer wants to rent, and either the customers last name or
his or her member ID number into the function. The function should return the due date
for the video. Due dates are three days from the date the video is rented. If the status for a
movie requested is listed as AVAILABLE in the TITLE_COPY table for one copy of this
title, then update this TITLE_COPY table and set the status to RENTED. If there is no
copy available, the function must return NULL. Then, insert a new record into the
RENTAL table identifying the booked date as todays date, the copy ID number, the
member ID number, the title ID number, and the expected return date. Be aware of
multiple customers with the same last name. In this case, have the function return NULL,
and display a list of the customers names that match and their ID numbers.
nd
a
g
in
r
e
ne
gi
n
E
f
o
e
ut
t
i
t
ns nly
I
i
o
h
d
e
n
s
Ga gy u
d
n nolo
a
y
h
c
sitA private
r
e
d. RESERVE_MOVIE:
procedure
that executes only if all the video copies
e
T
ivthe NEW_RENTAL
n
requested
in
procedure
have a status of RENTED. Pass the member ID
U
e
number
cl and the title ID number to this procedure. Insert a new record into the
a
r
O RESERVATION table and record the reservation date, member ID number, and title ID
c. RETURN_MOVIE: A public procedure that updates the status of a video (available,
rented, or damaged) and sets the return date. Pass the title ID, the copy ID, and the status
to this procedure. Check whether there are reservations for that title, and display a
message, if it is reserved. Update the RENTAL table and set the actual return date to
todays date. Update the status in the TITLE_COPY table based on the status parameter
passed into the procedure.
number. Print a message indicating that a movie is reserved and its expected date of
return.
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
DEFAULT
DEFAULT
DEFAULT
DEFAULT
NULL,
NULL,
NULL,
NULL);
FUNCTION new_rental
(memberid
IN rental.member_id%TYPE,
titleid
IN rental.title_id%TYPE)
RETURN DATE;
nd
a
g
FUNCTION new_rental
(membername IN member.last_name%TYPE,
titleid
IN rental.title_id%TYPE)
RETURN DATE;
PROCEDURE return_movie
(titleid
IN rental.title_id%TYPE,
copyid
IN rental.copy_id%TYPE,
sts
IN title_copy.status%TYPE);
END video_pkg;
/
SHOW ERRORS
in
r
e
ne
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
h
Package created. sit
c
r
e
e
T
iv
No errors. Un
le
c
a
VIDEO_PKG
Package Body
Or
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
in
r
e
ne
nd
a
g
o
e
t
PROCEDURE return_movie(
itu
t
titleid IN rental.title_id%TYPE,
s
n
nly
copyid IN rental.copy_id%TYPE, hi I
o
sts IN title_copy.status%TYPE)
ndIS use
a
v_dummy VARCHAR2(1);
d G ology
CURSOR res_csr IS an
SELECT *
ity echn
s
r
FROM reservation
e
T
niv
WHEREUtitle_id
= titleid;
BEGIN le
ac '' INTO v_dummy
OrSELECT
gi
n
E
FROM title
WHERE title_id = titleid;
UPDATE rental
SET act_ret_date = SYSDATE
WHERE title_id = titleid
AND copy_id = copyid AND act_ret_date IS NULL;
UPDATE title_copy
SET status = UPPER(sts)
WHERE title_id = titleid AND copy_id = copyid;
FOR res_rec IN res_csr LOOP
IF res_csr%FOUND THEN
DBMS_OUTPUT.PUT_LINE('Put this movie on hold -- '||
'reserved by member #' || res_rec.member_id);
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
exception_handler(SQLCODE, 'RETURN_MOVIE');
END return_movie;
Oracle Database 10g: Develop PL/SQL Program Units APS-31
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
in
r
e
ne
nd
a
g
gi
n
E
FUNCTION new_rental(
membername IN member.last_name%TYPE,
titleid
IN rental.title_id%TYPE) RETURN DATE IS
CURSOR copy_csr IS
SELECT * FROM title_copy
WHERE title_id = titleid
FOR UPDATE;
flag BOOLEAN := FALSE;
memberid member.member_id%TYPE;
CURSOR member_csr IS
SELECT member_id, last_name, first_name
FROM member
WHERE LOWER(last_name) = LOWER(membername)
ORDER BY last_name, first_name;
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
PROCEDURE new_member(
lname
IN member.last_name%TYPE,
fname
IN member.first_name%TYPE
DEFAULT NULL,
address
IN member.address%TYPE
DEFAULT NULL,
city
IN member.city%TYPE
DEFAULT NULL,
phone
IN member.phone%TYPE
DEFAULT NULL) IS
BEGIN
INSERT INTO member(member_id, last_name, first_name,
address, city, phone, join_date)
VALUES(member_id_seq.NEXTVAL, lname, fname,
address, city, phone, SYSDATE);
COMMIT;
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
4. Use the following scripts located in the E:\labs\PLPU\soln directory to test your
routines:
a. Add two members using sol_apb_04_a.sql.
SET SERVEROUTPUT ON
EXECUTE video_pkg.new_member('Haas', 'James', 'Chestnut Street',
'Boston', '617-123-4567')
EXECUTE video_pkg.new_member('Biri', 'Allan', 'Hiawatha Drive', 'New
York', '516-123-4567')
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
nd
a
g
in
r
e
ne
gi
n
E
f
o
e
ut
t
EXEC DBMS_OUTPUT.PUT_LINE(video_pkg.new_rental(109,
93))
i
t
s
y
In onl
i
h
26-FEB-04
nd use
PL/SQL procedure successfully completed.
a
G gy
d
n
lo
a
o
EXEC DBMS_OUTPUT.PUT_LINE(video_pkg.new_rental(107,
98))
n
y
t
h
i
c
rs Tback
e on: 21-FEB-04
eExpected
Movie reserved.
v
i
n successfully completed.
PL/SQL procedure
U
e
cl
a
r
EXEC
O DBMS_OUTPUT.PUT_LINE(video_pkg.new_rental('Biri', 97))
Warning! More than one member by this name.
112 Biri, Allan
108 Biri, Ben
PL/SQL procedure successfully completed.
EXEC DBMS_OUTPUT.PUT_LINE(video_pkg.new_rental(97, 97))
BEGIN DBMS_OUTPUT.PUT_LINE(video_pkg.new_rental(97, 97)); END;
*
ERROR at line 1:
ORA-20002: NEW_RENTAL has attempted to use a foreign key value that is
invalid
ORA-06512: at "ORA1.VIDEO_PKG", line 9
ORA-06512: at "ORA1.VIDEO_PKG", line 103
ORA-06512: at line 1
Oracle Database 10g: Develop PL/SQL Program Units APS-35
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
ERROR at line 1:
ORA-20999: Unhandled error in RETURN_MOVIE. Please contact your
application administrator with the following information: ORA-01403: no
data found
ORA-06512: at "ORA1.VIDEO_PKG", line 12
ORA-06512: at "ORA1.VIDEO_PKG", line 69
ORA-06512: at line 1
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
5. The business hours for the video store are 8:00 a.m. to 10:00 p.m., Sunday through Friday,
and 8:00 a.m. to 12:00 a.m. on Saturday. To ensure that the tables can be modified only
during these hours, create a stored procedure that is called by triggers on the tables.
a. Create a stored procedure called TIME_CHECK that checks the current time against
business hours. If the current time is not within business hours, use the
RAISE_APPLICATION_ERROR procedure to give an appropriate message.
CREATE OR REPLACE PROCEDURE time_check IS
BEGIN
IF ((TO_CHAR(SYSDATE,'D') BETWEEN 1 AND 6) AND
(TO_DATE(TO_CHAR(SYSDATE, 'hh24:mi'), 'hh24:mi') NOT BETWEEN
TO_DATE('08:00', 'hh24:mi') AND TO_DATE('22:00', 'hh24:mi')))
OR ((TO_CHAR(SYSDATE, 'D') = 7)
AND (TO_DATE(TO_CHAR(SYSDATE, 'hh24:mi'), 'hh24:mi') NOT BETWEEN
TO_DATE('08:00', 'hh24:mi') AND TO_DATE('24:00', 'hh24:mi'))) THEN
RAISE_APPLICATION_ERROR(-20999,
'Data changes restricted to office hours.');
END IF;
END time_check;
/
SHOW ERRORS
nd
a
g
in
r
e
ne
gi
n
E
f
o
e
ut
t
i
t
ns nly
I
Procedure created.
i
o
h
d
e
n
s
No errors.
Ga gy u
d
n nolo
a
y
b. Create a trigger on each
thecfive
h tables. Fire the trigger before data is inserted, updated,
it of e
s
r
e
and deleted ifrom
T Call your TIME_CHECK procedure from each of these
v the tables.
n
triggers.
eU
l
c
CREATE
ra OR REPLACE TRIGGER member_trig
O
BEFORE INSERT OR UPDATE OR DELETE ON member
CALL time_check
/
CREATE OR REPLACE TRIGGER rental_trig
BEFORE INSERT OR UPDATE OR DELETE ON rental
CALL time_check
/
CREATE OR REPLACE TRIGGER title_copy_trig
BEFORE INSERT OR UPDATE OR DELETE ON title_copy
CALL time_check
/
CREATE OR REPLACE TRIGGER title_trig
BEFORE INSERT OR UPDATE OR DELETE ON title
CALL time_check
/
Oracle Database 10g: Develop PL/SQL Program Units APS-37
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
Note: In order for your trigger to fail, you may need to change the time to be outside the
range of your current time in class. For example, while testing, you may want valid video
hours in your trigger to be from 6:00 p.m. to 8:00 a.m.
gi
n
E
f
o
e
ut
t
i
t
ns nly
I
i
o
h
d
e
n
s
Ga gy u
d
n nolo
a
y
sit Tech
r
e
ivtime zone usinge [+|-]HH:MI format such
n
-- Change your
-- time lreturns
e U a time between 6pm and 8am
c
ALTER
OraSESSION SET TIME_ZONE='-07:00';
Session altered.
SELECT SESSIONTIMEZONE,
TO_CHAR(CURRENT_DATE, 'DD-MON-YYYY HH24:MI') CURR_DATE
FROM DUAL;
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
'Vine Street',
'Vine Street',
*
ERROR at line 1:
ORA-20999: Unhandled error in NEW_MEMBER. Please contact your application
administrator with the following information: ORA-20999: Data changes
restricted to office hours.
ORA-06512: at "ORA1.TIME_CHECK", line 9
ORA-06512: at "ORA1.MEMBER_TRIG", line 1
ORA-04088: error during execution of trigger 'ORA1.MEMBER_TRIG'
ORA-06512: at "ORA1.VIDEO_PKG", line 12
ORA-06512: at "ORA1.VIDEO_PKG", line 171
ORA-06512: at line 1
nd
a
g
in
r
e
ne
o
e
t
itu
t
Session altered.
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
iv
n
eU
l
c
Ora
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
O
le
c
a
r
U
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Additional
Practice
Solutions
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
O
le
c
a
r
U
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
1. Evaluate each of the following declarations. Determine which of them are not legal
and explain why.
a. DECLARE
name,dept
VARCHAR2(14);
This is illegal because only one identifier per declaration is allowed.
b. DECLARE
test
NUMBER(5);
This is legal.
c. DECLARE
MAXSALARY
NUMBER(7,2) = 5000;
nd
a
g
in
r
e
ne
gi
n
E
Ora
f
o
e
ut
t
i
t
s
y
n
l
I
n
i
Character string
o
h
d
e
n
s
b. confirm := to_date('20-JAN-1999',
'DD-MON-YYYY');
Ga gy u
d
n nolo
Date
a
y
it ech + 500
c. sal :=rs(1000*12)
e
T
iv
Number
n
U
cled. test := FALSE;
Boolean
e. temp := temp1 < (temp2/ 3);
Boolean
f. var := sysdate;
Date
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
END;
gi
n
E
f
o
e
ut
t
i
t
2 END;
ns nly
I
i
o
h
d
e
n
s
/
a yu
G
g determine the data type and value of each
d
Evaluate the PL/SQL block given
oand
n above
l
a
o
of the following variables,
hnto the rules of scoping:
ity according
c
s
r
e
e of CUSTID
T at position 1 is:
ivvalue
a. The
n
e U300, and the data type is NUMBER
l
c
Ora b. The value of CUSTNAME at position 1 is:
custid := (custid *12) / 10;
Shape up Sports Club Jansports Club, and the data type is VARCHAR2
c. The value of NEW_CUSTID at position 2 is:
500, and the data type is NUMBER (or INTEGER)
d. The value of NEW_CUSTNAME at position 1 is:
Jansports Club, and the data type is VARCHAR2
e. The value of CUSTID at position 2 is:
1920, and the data type is NUMBER
f. The value of CUSTNAME at position 2 is:
Women Sports Club, and the data type is VARCHAR2
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
1996
Leap year
1886
1992
1824
Leap year
nd
a
g
SET SERVEROUTPUT ON
DECLARE
YEAR NUMBER(4) := &P_YEAR;
REMAINDER1 NUMBER(5,2);
REMAINDER2 NUMBER(5,2);
REMAINDER3 NUMBER(5,2);
BEGIN
REMAINDER1 := MOD(YEAR,4);
REMAINDER2 := MOD(YEAR,100);
REMAINDER3 := MOD(YEAR,400);
IF ((REMAINDER1 = 0 AND REMAINDER2 <> 0 )
OR REMAINDER3 = 0) THEN
DBMS_OUTPUT.PUT_LINE(YEAR || ' is a leap year');
ELSE
DBMS_OUTPUT.PUT_LINE (YEAR || ' is not a leap
year');
END IF;
END;
/
SET SERVEROUTPUT OFF
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
5. a. For the exercises below, you require a temporary table to store the results.
You can either create the table yourself or run the lab_ap_05.sql script
that will create the table for you. Create a table named TEMP with the
following three columns:
Column Name
NUM_STORE
CHAR_STORE
DATE_STORE
Data Type
Number
VARCHAR2
Date
Length
7,2
35
Key Type
Nulls/Unique
FK Table
FK Column
nd
a
g
(num_store NUMBER(7,2),
char_store VARCHAR2(35),
date_store DATE);
in
r
e
ne
gi
n
E
f
o
e
itut MESSAGE
t
b. Write a PL/SQL block that contains two s
variables,
y data typeandwith a length
nas VARCHAR2
l
I
DATE_WRITTEN. Declare MESSAGE
n
i
o Assign the following values to
h dataetype.
d
of 35 and DATE_WRITTEN as
DATE
n
s
Ga gy u
the variables:
d
nContents
lo
a
o
Variable
n
y
chis my first PL/SQL program.
sit TThis
MESSAGE
r
e
e
iv
DATE_WRITTEN
Current date
n
U
lethe values in appropriate columns of the TEMP table. Verify your results by
Store
c
a
r
SET SERVEROUTPUT ON
DECLARE
MESSAGE VARCHAR2(35);
DATE_WRITTEN DATE;
BEGIN
MESSAGE := 'This is my first PLSQL Program.';
DATE_WRITTEN := SYSDATE;
INSERT INTO temp(CHAR_STORE,DATE_STORE)
VALUES (MESSAGE,DATE_WRITTEN);
END;
/
SELECT * FROM TEMP;
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
gi
n
E
f
o
e
ut
t
i
t
s sal
7. Write a PL/SQL block to declare a variable
yto store the salary of an
ncalled
l
I
n
i
operform the following tasks:
h program,
employee. In the executable part ofd
the
e
n
s
u
a. Store an employee name
substitution variable:
Gain angyiSQL*Plus
d
o
SET SERVEROUTPUT
an hnol ON
y
t
i
c
P_LASTNAME
= Pataballa
rsDEFINE
e
e
T
v
i
b. n
Store his or her salary in the sal variable.
U
e
c.
If the salary is less than 3,000, give the employee a raise of 500 and
l
c
a
r
display the message <Employee Name>s salary updated in the
window.
d. If the salary is more than 3,000, print the employees salary in the format,
<Employee Name> earns ...
e. Test the PL/SQL block for the last names.
LAST_NAME
SALARY
Pataballa
4800
Greenberg
12000
Ernst
6000
Note: Undefine the variable that stores the employees name at the end of
the script.
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
BEGIN
SELECT salary INTO SAL
FROM employees
WHERE last_name = INITCAP('&&P_LASTNAME') FOR
UPDATE of salary;
LASTNAME := INITCAP('&P_LASTNAME');
IF SAL < 3000 THEN
UPDATE employees SET salary = salary + 500
WHERE last_name = INITCAP('&P_LASTNAME') ;
DBMS_OUTPUT.PUT_LINE (LASTNAME || '''s salary
updated');
ELSE
DBMS_OUTPUT.PUT_LINE (LASTNAME || ' earns '
nd
a
g
in
r
e
ne
||
TO_CHAR(SAL));
END IF;
gi
n
E
f
o
e
ut
END;
t
i
t
ns nly
/
I
i
o
h
SET SERVEROUTPUT OFF
d
e
n
s
u
UNDEFINE P_LASTNAME Ga
y
g
d
n nolo
a
y
t toestore
h the salary of an employee in an iSQL*Plus
8. Write a PL/SQL
c
siblock
r
e
substitution
iv variable. InT the executable part of the program, perform the following:
n
e UCalculate the annual salary as salary * 12.
l
c
Calculate the bonus as indicated below:
Ora
Annual Salary
Bonus
>= 20,000
2,000
19,999 - 10,000
1,000
<= 9,999
500
Display the amount of the bonus in the window in the following format:
The bonus is $..
Test the PL/SQL for the following test cases:
SALARY
BONUS
5000
2000
1000
1000
15000
2000
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
gi
n
E
9. a.
f
o
e
Execute the lab_ap_09_a.sql script toitcreate
ut a temporary table called
t
s
emp. Write a PL/SQL block to store an
the new department
ynumber,
nemployee
l
I
n
i
o
h
number, and the percentage increase
salary in iSQL*Plus substitution
nd inuthe
se
variables.
a
GON gy
d
SET SERVEROUTPUT
n
lo
a
o
n
DEFINE P_EMPNO
=
100
y
sit Tech = 10
r
DEFINE
P_NEW_DEPTNO
e
iv P_PER_INCREASE = 2
DEFINE
n
U
le
c
a
Or b. Update the department ID of the employee with the new department number,
and update the salary with the new salary. Use the emp table for the updates.
After the update is complete, display the message Update complete in the
window. If no matching records are found, display the message No Data
Found. Test the PL/SQL block for the following test cases.
EMPLOYEE_ID
NEW_DEPARTMENT_ID
% INCREASE
MESSAGE
100
20
10
30
126
40
Update
Complete
No Data
found
Update
Complete
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
f
o
e
ut
t
i
t
ns nly
I
i
o
h
d
e
n
s
Ga gy u
d
SET SERVEROUTPUT
n ONnolo
a
y
h
DECLARE sit
c
r
e
e
T IS
CURSOR
EMP_CUR
iv
n
U SELECT last_name,salary,hire_date
cle ENAME VARCHAR2(25);
gi
n
E
10. Create a PL/SQL block to declare an EMP_CUR cursor to select the employee
name, salary, and hire date from the employees table. Process each row from the
cursor, and if the salary is greater than 15,000 and the hire date is greater than 01FEB-1988, display the employee name, salary, and hire date in the window.
Ora
FROM EMPLOYEES;
SAL
NUMBER(7,2);
HIREDATE DATE;
BEGIN
OPEN EMP_CUR;
FETCH EMP_CUR INTO ENAME,SAL,HIREDATE;
WHILE EMP_CUR%FOUND
LOOP
IF SAL > 15000 AND HIREDATE >= TO_DATE('01-FEB1988','DD-MONYYYY') THEN
DBMS_OUTPUT.PUT_LINE (ENAME || ' earns ' ||
TO_CHAR(SAL)||
' and joined the organization on ' ||
TO_DATE(HIREDATE,'DDMon-YYYY'));
END IF;
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
b. Test the PL/SQL block for the following hire dates: 08-MAR-00
n,e25-JUN-97,
i
g
n
28-SEP-98, 07-FEB-99.
fE
o
ute
t
DECLARE
i
t
y IS
ns DATE)
l
CURSOR DATE_CURSOR(JOIN_DATE
I
n
i
o
h
d
SELECT employee_id,last_name,hire_date
FROM
e
n
s
a
u
employees
G gy
d
n
lo
WHERE HIRE_DATE
>JOIN_DATE
;
a
o
n
y
t
h
i
EMPNOrs employees.employee_id%TYPE;
c
e
e
T
v
employees.last_name%TYPE;
i
nENAME
U
HIREDATE
employees.hire_date%TYPE;
e HDATE employees.hire_date%TYPE
l
c
:=
'&P_HIREDATE';
ra
BEGIN
OPEN DATE_CURSOR(HDATE);
LOOP
FETCH DATE_CURSOR INTO EMPNO,ENAME,HIREDATE;
EXIT WHEN DATE_CURSOR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (EMPNO || ' ' || ENAME || '
' ||
HIREDATE);
END LOOP;
END;
/
SET SERVEROUTPUT OFF;
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
in
r
e
ne
nd
a
g
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
VARCHAR2
Number
Number
Length
20
8,2
nd
a
g
in
r
e
ne
gi
n
E
f
o
e
ut
t
i
t
with the information
s
b. Create a PL/SQL block to populate theIn
analysis
ytable
l
n
i
o substitution variable to store an
h iSQL*Plus
from the employees table. Usedan
e
n
s
u
employees last name. Ga
y
g
d
n nolo
a
y
sit TechON
SET SERVEROUTPUT
r
e
iv P_ENAME = Austin
n
DEFINE
eU
l
c
ra
c. Query the employees table to find if the number of years that the employee
has been with the organization is greater than five, and if the salary is less than
3,500, raise an exception. Handle the exception with an appropriate exception
handler that inserts the following values into the analysis table: employee
last name, number of years of service, and the current salary. Otherwise,
display Not due for a raise in the window. Verify the results by
querying the analysis table. Use the following test cases to test the PL/SQL
block.
LAST_NAME
MESSAGE
Austin
Nayer
Fripp
Khoo
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
in
r
e
ne
nd
a
g
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
O
le
c
a
r
U
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Additional Practices:
Table Descriptions
and Data
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
Part A
The tables and data used in part A are the same as those in Appendix B, Table
Descriptions and Data.
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E
Unauthorized reproduction or distribution prohibited Copyright 2012, Oracle and/or its affiliates
nd
a
g
in
r
e
ne
le
c
a
r
o
e
t
itu
t
s
In only
i
h
nd use
a
G gy
d
n
lo
a
o
n
y
sit Tech
r
e
niv
gi
n
E