9i PL-SQL Volume 2 PDF
9i PL-SQL Volume 2 PDF
9i PL-SQL Volume 2 PDF
Program Units
40056GC10
Production 1.0
July 2001
D33491
Author Copyright © Oracle Corporation, 1999, 2000, 2001. All rights reserved.
Publisher
Sheryl Domingue
Contents
Preface
Curriculum Map
2 Creating Procedures
Objectives 2-2
What Is a Procedure? 2-3
Syntax for Creating Procedures 2-4
Developing Procedures 2-5
Formal Versus Actual Parameters 2-6
Procedural Parameter Modes 2-7
Creating Procedures with Parameters 2-8
IN Parameters: Example 2-9
OUT Parameters: Example 2-10
Viewing OUT Parameters 2-12
IN OUT Parameters 2-13
Viewing IN OUT Parameters 2-14
Methods for Passing Parameters 2-15
DEFAULT Option for Parameters 2-16
Examples of Passing Parameters 2-17
Declaring Subprograms 2-18
Invoking a Procedure from an Anonymous PL/SQL Block 2-19
Invoking a Procedure from Another Procedure 2-20
Handled Exceptions 2-21
Unhandled Exceptions 2-23
Removing Procedures 2-25
Benefits of Subprograms 2-26
Summary 2-27
Practice 2 Overview 2-29
iii
3 Creating Functions
Objectives 3-2
Overview of Stored Functions 3-3
Syntax for Creating Functions 3-4
Creating a Function 3-5
Creating a Stored Function by Using iSQL*Plus 3-6
Creating a Stored Function by Using iSQL*Plus: Example 3-7
Executing Functions 3-8
Executing Functions: Example 3-9
Advantages of User-Defined Functions in SQL Expressions 3-10
Invoking Functions in SQL Expressions: Example 3-11
Locations to Call User-Defined Functions 3-12
Restrictions on Calling Functions from SQL Expressions 3-13
Restrictions on Calling from SQL 3-15
Removing Functions 3-16
Procedure or Function? 3-17
Comparing Procedures and Functions 3-18
Benefits of Stored Procedures and Functions 3-19
Summary 3-20
Practice 3 Overview 3-21
4 Managing Subprograms
Objectives 4-2
Required Privileges 4-3
Granting Access to Data 4-4
Using Invoker’s-Rights 4-5
Managing Stored PL/SQL Objects 4-6
USER_OBJECTS 4-7
List All Procedures and Functions 4-8
USER_SOURCE Data Dictionary View 4-9
List the Code of Procedures and Functions 4-10
USER_ERRORS 4-11
Detecting Compilation Errors: Example 4-12
List Compilation Errors by Using USER_ERRORS 4-13
List Compilation Errors by Using SHOW ERRORS 4-14
DESCRIBE in iSQL*Plus 4-15
Debugging PL/SQL Program Units 4-16
Summary 4-17
Practice 4 Overview 4-19
iv
5 Creating Packages
Objectives 5-2
Overview of Packages 5-3
Components of a Package 5-4
Referencing Package Objects 5-5
Developing a Package 5-6
Creating the Package Specification 5-8
Declaring Public Constructs 5-9
Creating a Package Specification: Example 5-10
Creating the Package Body 5-11
Public and Private Constructs 5-12
Creating a Package Body: Example 5-13
Invoking Package Constructs 5-15
Declaring a Bodiless Package 5-17
Referencing a Public Variable from a Stand-Alone Procedure 5-18
Removing Packages 5-19
Guidelines for Developing Packages 5-20
Advantages of Packages 5-21
Summary 5-23
Practice 5 Overview 5-26
v
7 Oracle Supplied Packages
Objectives 7-2
Using Supplied Packages 7-3
Using Native Dynamic SQL 7-4
Execution Flow 7-5
Using the DBMS_SQL Package 7-6
Using DBMS_SQL 7-8
Using the EXECUTE IMMEDIATE Statement 7-9
Dynamic SQL Using EXECUTE IMMEDIATE 7-11
Using the DBMS_DDL Package 7-12
Using DBMS_JOB for Scheduling 7-13
DBMS_JOB Subprograms 7-14
Submitting Jobs 7-15
Changing Job Characteristics 7-17
Running, Removing, and Breaking Jobs 7-18
Viewing Information on Submitted Jobs 7-19
Using the DBMS_OUTPUT Package 7-20
Interacting with Operating System Files 7-21
What Is the UTL_FILE Package? 7-22
File Processing Using the UTL_FILE Package 7-23
UTL_FILE Procedures and Functions 7-24
Exceptions Specific to the UTL_FILE Package 7-25
The FOPEN and IS_OPEN Functions 7-26
Using UTL_FILE 7-27
The UTL_HTTP Package 7-29
Using the UTL_HTTP Package 7-30
Using the UTL_TCP Package 7-31
Oracle-Supplied Packages 7-32
Summary 7-37
Practice 7 Overview 7-38
vi
Managing BFILEs 8-12
Preparing to Use BFILEs 8-13
The BFILENAME Function 8-14
Loading BFILEs 8-15
Migrating from LONG to LOB 8-17
The DBMS_LOB Package 8-19
DBMS_LOB.READ and DBMS_LOB.WRITE 8-22
Adding LOB Columns to a Table 8-23
Populating LOB Columns 8-24
Updating LOB by Using SQL 8-26
Updating LOB by Using DBMS_LOB in PL/SQL 8-27
Selecting CLOB Values by Using SQL 8-28
Selecting CLOB Values by Using DBMS_LOB 8-29
Selecting CLOB Values in PL/SQL 8-30
Removing LOBs 8-31
Temporary LOBs 8-32
Creating a Temporary LOB 8-33
Summary 8-34
Practice 8 Overview 8-35
9 Creating Database Triggers
Objectives 9-2
Types of Triggers 9-3
Guidelines for Designing Triggers 9-4
Database Trigger: Example 9-5
Creating DML Triggers 9-6
DML Trigger Components 9-7
Firing Sequence 9-11
Syntax for Creating DML Statement Triggers 9-13
Creating DML Statement Triggers 9-14
Testing SECURE_EMP 9-15
Using Conditional Predicates 9-16
Creating a DML Row Trigger 9-17
Creating DML Row Triggers 9-18
Using OLD and NEW Qualifiers 9-19
Using OLD and NEW Qualifiers: Example Using Audit_Emp_Table 9-20
Restricting a Row Trigger 9-21
INSTEAD OF Triggers 9-22
Creating an INSTEAD OF Trigger 9-23
Creating an INSTEAD OF Trigger 9-26
Differentiating Between Database Triggers and Stored Procedures 9-27
Differentiating Between Database Triggers and Form Builder Triggers 9-28
Managing Triggers 9-29
DROP TRIGGER Syntax 9-30
vii
Trigger Test Cases 9-31
Trigger Execution Model and Constraint Checking 9-32
Trigger Execution Model and Constraint Checking: Example 9-33
A Sample Demonstration for Triggers Using Package Constructs 9-34
After Row and After Statement Triggers 9-35
Demonstration: VAR_PACK Package Specification 9-36
Demonstration: Using the AUDIT_EMP Procedure 9-38
Summary 9-39
Practice 9 Overview 9-40
viii
11 Managing Dependencies
Objectives 11-2
Understanding Dependencies 11-3
Dependencies 11-4
Local Dependencies 11-5
A Scenario of Local Dependencies 11-6
Displaying Direct Dependencies by Using USER_DEPENDENCIES 11-7
Displaying Direct and Indirect Dependencies 11-8
Displaying Dependencies 11-9
Another Scenario of Local Dependencies 11-10
A Scenario of Local Naming Dependencies 11-11
Understanding Remote Dependencies 11-12
Concepts of Remote Dependencies 11-13
REMOTE_DEPENDENCIES_MODE Parameter 11-14
Remote Dependencies and Time Stamp Mode 11-15
Remote Procedure B Compiles at 8:00 a.m. 11-16
Local Procedure A Compiles at 9:00 a.m. 11-17
Execute Procedure A 11-18
Remote Procedure B Recompiled at 11:00 a.m. 11-19
Execute Procedure A 11-20
Signature Mode 11-21
Recompiling a PL/SQL Program Unit 11-22
Unsuccessful Recompilation 11-23
Successful Recompilation 11-24
Recompilation of Procedures 11-25
Packages and Dependencies 11-26
Summary 11-28
Practice 11 Overview 11-29
ix
x
Additional
Practices
Additional Practices Overview
These additional practices are provided as a supplement to the course Develop PL/SQL Program Units.
In these practices, you apply the concepts that you learned in Develop PL/SQL Program Units.
The additional practices comprise of two parts:
Part A provides supplemental practice to create stored procedures, functions, packages, and triggers,
and to use the Oracle-supplied packages with iSQL*Plus as the development environment. The tables
used in this portion of the additional practices include EMPLOYEES, JOBS, JOB_HISTORY, and
DEPARTMENTS.
Part B is a case study which can be completed at the end of the course. This part supplements the
practices for creating and managing program units. The tables used in the case study are based on a
video database and contain the TITLE, TITLE_COPY, RENTAL, RESERVATION, and MEMBER
tables.
An entity relationship diagram is provided at the start of part A and part B. Each entity relationship
diagram displays the table entities and their relationships. More detailed definitions of the tables and
the data contained in each of the tables is provided in the appendix Additional Practices: Table
Descriptions and Data.
Human Resources
1. In this practice, create a program to add a new job into the JOBS table.
a. Create a stored procedure called ADD_JOBS to enter a new order into the JOBS table.
The procedure should accept three parameters. The first and second parameters supplies 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. Disable the trigger SECURE_DML before invoking the procedure. Invoke the procedure to add a
new job with job ID SY_ANAL, job title System Analyst, and minimum salary of 6,000.
c. Verify that a row was added and remember the new job ID for use in the next exercise.
Commit the changes.
2. In this practice, create a program to add a new row to the JOB_HISTORY table for an existing
employee.
Note: Disable all triggers on the EMPLOYEES, JOBS, and JOB_HISTORY tables before invoking
the procedure in part b. Enable all these triggers after executing the procedure.
a. Create a stored procedure called ADD_JOB_HIST to enter a new row into the JOB_HISTORY
table for an employee who is changing his job to the new job ID that you created in question 1b.
Use the employee ID of the employee who is changing the job and the new job ID for the
employee as parameters. Obtain the row corresponding to this employee ID from the
EMPLOYEES table and insert it into the JOB_HISTORY table. Make hire date of this employee
as the start date and today's date as end date for this row in the JOB_HISTORY table.
Change the hire date of this employee in the EMPLOYEES table to today's date. Update the job
ID of this employee to the job ID passed as parameter (Use the job ID of the job created in
question 1b) and salary equal to minimum salary for that job ID + 500.
Include exception handling to handle an attempt to insert a nonexistent employee.
b. Disable triggers (Refer to the note at the beginning of this question.)
Execute the procedure with employee ID 106 and job ID SY_ANAL as parameters.
Enable the triggers that you disabled.
c. Query the tables to view your changes, and then commit the changes.
c. Query the JOBS table to view your changes, and then commit the changes.
Note: These exercises can be used for extra practice when discussing how to create functions.
5. Create a program to retrieve the number of years of service for a specific employee.
a. Create a stored function called GET_SERVICE_YRS 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 function. You can use the following data:
EXECUTE DBMS_OUTPUT.PUT_LINE(get_service_yrs(999))
Hint: The above statement should produce an error message because there is no employee
with employee ID 999.
EXECUTE DBMS_OUTPUT.PUT_LINE ('Approximately .... ' ||
get_service_yrs(106) || ' years')
Hint: The above statement should be successful and return the number of years of service
for employee with employee ID 106.
c. Query the JOB_HISTORY and EMPLOYEES tables for the specified employee to verify
that the modifications are accurate.
Note: These exercises can be used for extra practice when discussing how to create packages.
7. Create a package specification and body called EMP_JOB_PKG that contains your ADD_JOBS,
ADD_JOB_HIST, and UPD_SAL procedures, as well as your GET_SERVICE_YRS function.
a. Make all the constructs public. Consider whether you still need the stand-alone procedures
and functions that you just packaged.
b. Disable all the triggers before invoking the procedure and enable them after invoking the
procedure, as suggested in question 2b.
Invoke your ADD_JOBS procedure to create a new job with ID PR_MAN, job title Public
Relations Manager, and salary of 6,250.
Invoke your ADD_JOB_HIST procedure to modify the job of employee with employee ID
110 to job ID PR_MAN.
Hint: All of the above calls to the functions should be successful.
c. 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.
9. In this practice, create a trigger to ensure that the job ID of any new employee being hired to
department 80 (the Sales department) is a sales manager or representative.
a. Disable all the previously created triggers as discussed in question 2b.
b. Create a trigger called CHK_SALES_JOB.
Fire the trigger before every row that is changed after insertions and updates to the JOB_ID
column in the EMPLOYEES table. Check that the new employee has a job ID of SA_MAN or
SA_REP in the EMPLOYEES table. Add exception handling and provide an appropriate message
so that the update fails if the new job ID is not that of a sales manager or representative.
c. Test the trigger. You can use the following data:
UPDATE employees
SET job_id = 'AD_VP'
WHERE employee_id = 106;
UPDATE employees
SET job_id = 'AD_VP'
WHERE employee_id = 179;
UPDATE employees
SET job_id = 'SA_MAN'
WHERE employee_id = 179;
Hint: The middle statement should produce the error message specified in your trigger.
e. Enable all the triggers that you previously disabled, as discussed in question 2b.
10. In this practice, 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.
Fire the trigger before every row that is changed when data 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 that 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.
b. Test the trigger. You can use the following data:
SELECT * FROM jobs WHERE job_id = 'SY_ANAL';
TITLE
for #* ID
RESERVATION * title
#* reservation date the subject * description
of o rating
set up for o category
o release date
available as
a copy
TITLE_COPY
#* ID
* status
the subject of
responsible
for
2. Create a package named VIDEO 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 customer’s 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 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 today's 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.
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
today’s date. Update the status in the TITLE_COPY table based on the status parameter
passed into the procedure.
d. RESERVE_MOVIE: A private procedure that executes only if all of the video 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 out 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 to this procedure the SQLCODE number, 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.
EXECUTE video.new_member
('Biri', 'Allan', 'Hiawatha Drive', 'New York', '516 -123-4567')
b. Disable the trigger SECURE_DML before invoking the procedure. Invoke the procedure to add a new
job with job ID SY_ANAL, job title System Analyst, and minimum salary of 6,000.
ALTER TRIGGER secure_employees DISABLE;
EXECUTE add_jobs ('SY_ANAL', 'System Analyst', 6000)
c. Verify that a row was added and remember the new job ID for use in the next exercise.
Commit the changes.
SELECT *
FROM jobs
WHERE job_id = 'SY_ANAL';
c. Query the tables to view your changes, and then commit the changes.
SELECT * FROM job_history
WHERE employee_id = 106;