Unit – 4
UNIT - IV
Packages: Package Architecture, Package Specification, Prototype Features, Serially Reusable
Precompiler Directive, Variables, Types, Components: Functions and Procedures, Package Body,
Prototype Features, Variables, Types, Components: Functions and Procedures, Definer vs. Invoker
Rights Mechanics, Managing Packages in the Database Catalog, Finding, Validating, and Describing
Packages, Checking Dependencies, Comparing Validation Methods: Timestamp vs. Signature.
Package Architecture:
The PL/SQL runtime system is a technology and not an independent product. This technology is
actually like an engine that exhibits PL/SQL blocks, subprograms like functions and procedures. This
engine can be installed in an Oracle Server or in application development tools such as Oracle Form
Builder, Oracle Reports Builder etc.
PL/SQL can reside in two environments –
1. The Oracle Server
2. The Oracle tools
These two environments are independent of each other. In either environment, the PL/SQL engine
accepts any valid PL/SQL block as input. The PL/SQL engine executes the procedural part of the
statements and sends the SQL statement executer in the Oracle Server. A single transfer is required to
send the block from the application to the Oracle Server, thus improving performance, especially in a
Client-Server network. PL/SQL code can also be stored in the Oracle server as subprograms that can be
referenced by any number of applications connected to the database.
Creating a package specification
Creating a package specification in PL/SQL defines the interface to the package and which
functionalities are provided by the packages. The specification of the package works as the connection
between the package and its users and defines the procedure, function, types, variables, and exceptions
that are accessible in public.
Step-by-step process to creating a specification of the package
Step 1: Create Package specification
First, you can start the 'CREATE PACKAGE' statement. The statement initiates the creation of the
package specification and is followed by the package name.
The syntax for creating the package specification:
CREATE PACKAGE package_name AS
Step 2: Declare global variables and constants
This step is optional, if the package requires any global constants or global variables, you can declare
the constants and variables in the package specification. If you declare the variables and constants in the
package specification, you can access these variables and constants throughout the package.
The syntax for declaring constants and variables:
g_variable NUMBER := 0;
constants CONSTANT VARCHAR2(20) := 'CONSTANT_VALUE';
Step 3: Declare public procedures and functions
In this step, you can define the procedures and functions that you will want to expose other PL/SQL
code outside of the package. You can declare every procedure and every function and also with the
return type and its parameter.
The syntax for declaring the procedures and functions:
PROCEDURE public_procedure(param1 IN NUMBER, param2 OUT VARCHAR2);
FUNCTION public_function(param IN VARCHAR2) RETURN NUMBER;
Step 4: End the package specification
At the end of the package specification, you need to close the package specification with the help of
"END" keyword.
The syntax for closing the specification of the package:
END package_name;
In PL/SQL, "prototype features" generally refer to the ability to create reusable code structures like
procedures and functions with predefined parameters and return types, allowing developers to design a
"prototype" of a functionality that can be easily integrated and called throughout the application,
essentially acting as a blueprint for future implementation and ensuring consistency across the
codebase.
Key aspects of prototype features in PL/SQL:
Parameterization:
Defining input and output parameters with specific data types allows for flexibility in how the
procedure or function is used, enabling adaptation to different scenarios.
Data Type Specificity:
By specifying the data types of parameters and return values, PL/SQL enforces data integrity
and improves code readability
Overloading:
The ability to create multiple procedures or functions with the same name but different parameter lists,
allowing for different behaviors based on the data provided.
Modular Design:
Breaking down complex operations into smaller, reusable procedures and functions promotes code
organization and maintainability.
In PL/SQL, "Serially Reusable" refers to a pragma (compiler directive) called
SERIALLY_REUSABLE which instructs the database to allocate package variables only for the
duration of a single call to the package, essentially reusing the memory space for each subsequent call
within the same session, thereby optimizing memory usage, particularly in scenarios with high
concurrent access to the same package functions or procedures
Syntax as shown:
PRAGMA SERIALLY_REUSABLE;
For packages with a body, you should code the pragma in the specification and body. You cannot only
code the pragma in the body. The illustration below shows how a public variable in a serially reusable
package behaves across the call boundaries:
CREATE OR REPLACE PACKAGE sr_pkg IS
PRAGMA SERIALLY_REUSABLE;
num NUMBER := 0;
PROCEDURE init_pkg_state(n NUMBER);
PROCEDURE print_pkg_state;
END sr_pkg;
/
CREATE OR REPLACE PACKAGE BODY sr_pkg IS
PRAGMA SERIALLY_REUSABLE;
/* Initialize package state. */
PROCEDURE init_pkg_state (n NUMBER) IS
BEGIN
sr_pkg.num := n;
END;
/* Print package state. */
PROCEDURE print_pkg_state IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Num is: ' || sr_pkg.num);
END;
END sr_pkg;
BEGIN
/* Initialize package state. */
sr_pkg.init_pkg_state(4);
/* On same server call, print package state. */
sr_pkg.print_pkg_state; -- prints 4
END;
-- subsequent server call
BEGIN
-- package's public variable will initialized to its
-- default value automatically
sr_pkg.print_pkg_state; -- prints 0
END;
1. Precompiler Directives in PL/SQL
Precompiler directives are special instructions for the Oracle Precompiler, which is used in embedded
SQL applications. These directives help in error handling, conditional compilation, and improving
performance.
Common Precompiler Directives:
Directive Description
EXEC SQL INCLUDE filename Includes an external file in the PL/SQL program.
EXEC SQL WHENEVER SQLERROR Specifies actions on SQL errors.
EXEC SQL WHENEVER NOT FOUND Specifies actions when no rows are found.
PRAGMA Allows a procedure or function to run independently of the
AUTONOMOUS_TRANSACTION main transaction.
Associates an application-specific error number with an
PRAGMA EXCEPTION_INIT
exception.
Improves memory usage for packages that are not
PRAGMA SERIALLY_REUSABLE
frequently used.
2. Variables in PL/SQL
Variables in PL/SQL store data and allow manipulation within programs. They must be declared before
use.
Variable Declaration Syntax:
variable_name datatype [CONSTANT] [:= initial_value];
Example:
DECLARE
emp_name VARCHAR2(50);
emp_salary NUMBER(10,2) := 50000;
BEGIN
DBMS_OUTPUT.PUT_LINE('Employee Salary: ' || emp_salary);
END;
Types of Variables:
1. Scalar Variables – Hold a single value (e.g., NUMBER, VARCHAR2, DATE).
2. Composite Variables – Store multiple values (e.g., RECORD, TABLE).
3. Reference Variables – Pointers to database values (e.g., REF CURSOR).
4. LOB Variables – Handle large objects like CLOB, BLOB, BFILE.
3. Data Types in PL/SQL
PL/SQL supports several data types grouped into categories:
Type Description Example
Scalar Single value variables NUMBER, VARCHAR2, BOOLEAN, DATE
Composite Group multiple values RECORD, TABLE, VARRAY
Reference Pointers to data REF CURSOR
LOB Store large data CLOB, BLOB, NCLOB
Example of Different Data Types:
DECLARE
emp_id NUMBER(5);
emp_name VARCHAR2(100);
emp_salary NUMBER(10,2);
hire_date DATE;
is_manager BOOLEAN;
BEGIN
emp_id := 101;
emp_name := 'John Doe';
emp_salary := 60000;
hire_date := SYSDATE;
is_manager := TRUE;
END;
/
4. Components of PL/SQL
PL/SQL consists of several key components that form the structure of a PL/SQL block.
Main Components:
1. PL/SQL Block Structure
o Declaration Section – Declares variables, constants, cursors, etc.
o Execution Section – Contains SQL and procedural statements.
o Exception Handling Section – Handles errors.
2. Procedures and Functions
o Procedures: Perform actions (e.g., inserting data).
o Functions: Return values (e.g., calculating total salary).
Packages
Group related procedures, functions, and variables.
Triggers
Execute automatically based on events (e.g., AFTER INSERT).
Cursors
Retrieve and process multiple rows.
Example of a Simple PL/SQL Block:
DECLARE
v_message VARCHAR2(50);
BEGIN
v_message := 'Hello, PL/SQL!';
DBMS_OUTPUT.PUT_LINE(v_message);
END;
/
Packages, Functions, and Procedures in PL/SQL:
1. Packages in Functions and Procedures
A package consists of two parts:
1. Package Specification (Interface) – Declares functions, procedures, and variables.
2. Package Body (Implementation) – Implements the declared functions and procedures.
Example: Creating a Package with Functions and Procedures
We will create a package that manages employee data.
Step 1: Package Specification
CREATE OR REPLACE PACKAGE employee_pkg AS
-- Public Procedure
PROCEDURE add_employee(emp_id NUMBER, emp_name VARCHAR2, emp_salary
NUMBER);
-- Public Function
FUNCTION get_employee_salary(emp_id NUMBER) RETURN NUMBER;
END employee_pkg;
/
2. Package Body in PL/SQL
The package body contains the actual implementation of the functions and procedures declared in the
specification.
Step 2: Package Body Implementation
CREATE OR REPLACE PACKAGE BODY employee_pkg AS
-- Implementation of Procedure
PROCEDURE add_employee(emp_id NUMBER, emp_name VARCHAR2, emp_salary
NUMBER) IS
BEGIN
INSERT INTO employees (id, name, salary) VALUES (emp_id, emp_name, emp_salary);
COMMIT;
END add_employee;
-- Implementation of Function
FUNCTION get_employee_salary(emp_id NUMBER) RETURN NUMBER IS
emp_salary NUMBER;
BEGIN
SELECT salary INTO emp_salary FROM employees WHERE id = emp_id;
RETURN emp_salary;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL; -- Returns NULL if no employee found
END get_employee_salary;
END employee_pkg;
/
3. Using the Package in PL/SQL
Once the package is created, we can use its functions and procedures in SQL or PL/SQL blocks.
Calling the Procedure
BEGIN
employee_pkg.add_employee(101, 'John Doe', 60000);
END;
/
Calling the Function
DECLARE
salary NUMBER;
BEGIN
salary := employee_pkg.get_employee_salary(101);
DBMS_OUTPUT.PUT_LINE('Salary: ' || salary);
END;
/
Definer vs. Invoker Rights:
1. Definer Rights (AUTHID DEFINER)
Default behavior in PL/SQL.
The package runs using the privileges of the schema (definer) that created it.
The invoker (caller) does not need privileges on the underlying tables.
Useful for maintaining centralized control over data access.
Example of a Package with Definer Rights
-- Create the package specification
CREATE OR REPLACE PACKAGE emp_pkg AUTHID DEFINER AS
PROCEDURE add_employee(emp_id NUMBER, emp_name VARCHAR2, emp_salary
NUMBER);
FUNCTION get_employee_salary(emp_id NUMBER) RETURN NUMBER;
END emp_pkg;
/
-- Create the package body
CREATE OR REPLACE PACKAGE BODY emp_pkg AS
PROCEDURE add_employee(emp_id NUMBER, emp_name VARCHAR2, emp_salary
NUMBER) IS
BEGIN
INSERT INTO employees (id, name, salary) VALUES (emp_id, emp_name, emp_salary);
COMMIT;
END add_employee;
FUNCTION get_employee_salary(emp_id NUMBER) RETURN NUMBER IS
emp_salary NUMBER;
BEGIN
SELECT salary INTO emp_salary FROM employees WHERE id = emp_id;
RETURN emp_salary;
END get_employee_salary;
END emp_pkg;
/
Behavior:
The package executes with the privileges of the definer (schema owner).
Even if a user without access to the employees table executes emp_pkg.get_employee_salary(),
the query still runs successfully if the package owner has privileges.
2. Invoker Rights (AUTHID CURRENT_USER)
The package runs using the privileges of the user invoking it.
The user must have explicit privileges on the referenced tables.
Useful for making generic utility packages that work across different schemas.
Example of a Package with Invoker Rights
-- Create the package specification
CREATE OR REPLACE PACKAGE emp_pkg AUTHID CURRENT_USER AS
PROCEDURE add_employee(emp_id NUMBER, emp_name VARCHAR2, emp_salary
NUMBER);
FUNCTION get_employee_salary(emp_id NUMBER) RETURN NUMBER;
END emp_pkg;
/
-- Create the package body
CREATE OR REPLACE PACKAGE BODY emp_pkg AS
PROCEDURE add_employee(emp_id NUMBER, emp_name VARCHAR2, emp_salary
NUMBER) IS
BEGIN
INSERT INTO employees (id, name, salary) VALUES (emp_id, emp_name, emp_salary);
COMMIT;
END add_employee;
FUNCTION get_employee_salary(emp_id NUMBER) RETURN NUMBER IS
emp_salary NUMBER;
BEGIN
SELECT salary INTO emp_salary FROM employees WHERE id = emp_id;
RETURN emp_salary;
END get_employee_salary;
END emp_pkg;
/
Behavior:
The package executes with the privileges of the calling user.
The caller must have explicit privileges on the employees table.
If a user without SELECT privileges on employees calls get_employee_salary(), the query fails.
1. Rights Mechanics in PL/SQL Packages
PL/SQL packages execute under Definer Rights or Invoker Rights, affecting security and privileges.
Definer Rights (AUTHID DEFINER)
Default behavior.
The package executes with the privileges of the schema that owns it.
The caller does not need explicit table privileges.
Useful for centralized access control.
Example of Definer Rights Package:
CREATE OR REPLACE PACKAGE emp_pkg AUTHID DEFINER AS
FUNCTION get_salary(emp_id NUMBER) RETURN NUMBER;
END emp_pkg;
/
CREATE OR REPLACE PACKAGE BODY emp_pkg AS
FUNCTION get_salary(emp_id NUMBER) RETURN NUMBER IS
emp_salary NUMBER;
BEGIN
SELECT salary INTO emp_salary FROM employees WHERE id = emp_id;
RETURN emp_salary;
END get_salary;
END emp_pkg;
/
Invoker Rights (AUTHID CURRENT_USER)
Executes with the caller’s privileges.
The caller must have access to the underlying tables.
Useful for multi-schema utilities.
Example of Invoker Rights Package
CREATE OR REPLACE PACKAGE emp_pkg AUTHID CURRENT_USER AS
FUNCTION get_salary(emp_id NUMBER) RETURN NUMBER;
END emp_pkg;
/
2. Managing Packages in the Database Catalog
Oracle stores package metadata in the Data Dictionary, which can be queried using system views.
Important Views for Managing Packages
View Description
USER_OBJECTS Lists objects owned by the current user.
ALL_OBJECTS Lists objects accessible to the user.
DBA_OBJECTS Lists all objects in the database (admin privileges required).
USER_PROCEDURES Lists functions and procedures in packages.
ALL_PROCEDURES Lists accessible functions and procedures.
DBA_PROCEDURES Lists all functions and procedures (admin only).
Finding Packages in the Database
SELECT object_name, status
FROM user_objects
WHERE object_type = 'PACKAGE';
3. Validating Packages in PL/SQL
Validation ensures that packages are compiled and valid.
Checking if a Package is Valid
SELECT object_name, status
FROM user_objects
WHERE object_type = 'PACKAGE' AND status <> 'VALID';
4. Finding Dependencies of a Package
To check which objects depend on a package:
SELECT name, type, referenced_name, referenced_type
FROM user_dependencies
WHERE referenced_name = 'EMP_PKG';
5. Dropping and Managing Packages
Dropping a Package
DROP PACKAGE emp_pkg;
Checking Dependencies in PL/SQL
Oracle manages dependencies between objects (tables, views, functions, packages) to ensure
consistency.
Checking Dependencies Using System Views
View Description
USER_DEPENDENCIES Shows dependencies for objects owned by the current user.
ALL_DEPENDENCIES Shows dependencies for objects accessible to the user.
DBA_DEPENDENCIES Shows dependencies for all objects (requires DBA privileges).
Example: Finding Dependencies of a Package
SELECT name, type, referenced_name, referenced_type
FROM user_dependencies
WHERE name = 'EMP_PKG';
This query retrieves objects that EMP_PKG depends on (e.g., tables, functions).
Example: Finding Objects Dependent on a Package
SELECT name, type
FROM user_dependencies
WHERE referenced_name = 'EMP_PKG';
3. Validation Methods in PL/SQL
When an object (e.g., a package) depends on another object (e.g., a table), it must be revalidated when
the referenced object changes. Oracle uses two validation methods:
3.1 Timestamp Validation
Oracle compares the timestamp of the dependent object with its referenced object.
If the timestamp changes, the dependent object becomes invalid and must be recompiled.
Issue: Even if there are no actual changes in structure, changing an object forces recompilation.
Example of Timestamp-Based Invalidations
ALTER TABLE employees ADD (bonus NUMBER);
3.2 Signature Validation
Oracle compares the interface signature (e.g., function parameters, return types) instead of
timestamps.
If only the implementation (body) changes, dependent objects remain valid.
More efficient and reduces unnecessary recompilations.
Enabling Signature-Based Dependency Checking
ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL = 2;
ALTER SYSTEM SET PLSQL_CODE_TYPE = NATIVE;