PLSQL Packages
PLSQL Packages
PL/SQL Packages
What is a Package:
A package is a schema object that groups logically related PL/SQL types, variables,
constants, subprograms, cursors, and exceptions.
A package is compiled and stored in the database, where many applications can
share its contents.
A package always has a specification, which declares the public items that can be
referenced from outside the package.
If the public items include cursors or subprograms, then the package must also have
a body. The body must define queries for public cursors and code for public
subprograms.
The AUTHID clause of the package specification determines whether the
subprograms and cursors in the package run with the privileges of their definer (the
default) or invoker.
The ACCESSIBLE BY clause of the package specification lets you specify a white list of
PL/SQL units that can access the package. You use this clause in situations like these:
You implement a PL/SQL application as several packages—one package that
provides the application programming interface (API) and helper packages to
do the work. You want clients to have access to the API, but not to the helper
packages. Therefore, you omit the ACCESSIBLE BY clause from the API package
specification and include it in each helper package specification, where you
specify that only the API package can access the helper package.
You create a utility package to provide services to some, but not all, PL/SQL
units in the same schema. To restrict use of the package to the intended units,
you list them in the ACCESSIBLE BY clause in the package specification.
Modularity
Packages let you encapsulate logically related types, variables, constants,
subprograms, cursors, and exceptions in named PL/SQL modules. You can make each
package easy to understand, and make the interfaces between packages simple,
clear, and well defined.
Page 2 of 13
Added Functionality
Package public variables and cursors can persist for the life of a session. They can be
shared by all subprograms that run in the environment. They let you maintain data
across transactions without storing it in the database.
Better Performance
The first time you invoke a package subprogram, Oracle Database loads the whole
package into memory. Subsequent invocations of other subprograms in same the
package require no disk I/O. Packages prevent cascading dependencies and
unnecessary recompiling. For example, if you change the body of a package function,
Oracle Database does not recompile other subprograms that invoke the function,
because these subprograms depend only on the parameters and return value that
are declared in the specification.
Note:
You cannot reference host variables from inside a package.
Page 3 of 13
Package Specification
A package specification declares public items. The scope of a public item is the
schema of the package. A public item is visible everywhere in the schema. To
reference a public item that is in scope but not visible, qualify it with the package
name. Each public item declaration has all information needed to use the item.
CREATE PACKAGE Statement:
The CREATE PACKAGE statement creates or replaces the specification for a stored
package.
Prerequisite: To create or replace a package in your schema, you must have the
CREATE PROCEDURE system privilege. To create or replace a package in another
user's schema, you must have the CREATE ANY PROCEDURE system privilege.
To embed a CREATE PACKAGE statement inside the database precompiler program,
you must terminate the statement with the keyword END-EXEC followed by the
embedded SQL statement terminator for the specific language.
Syntax:
Page 4 of 13
Semantics:
OR REPLACE
Re-creates the procedure if it exists, and recompiles it. Users who were granted
privileges on the procedure before it was redefined can still access the procedure
without being regranted the privileges. If any function-based indexes depend on the
procedure, then the database marks the indexes DISABLED.
item_list_1
Defines every type in the package and declares every cursor and subprogram in the
package. Every declaration must have a corresponding definition in the package
body. The headings of corresponding declarations and definitions must match word
for
word, except for white space.
Restriction on item_list_1
PRAGMA AUTONOMOUS_TRANSACTION cannot appear here.
DECLARE
aa_var aa_pkg.aa_type;
BEGIN
aa_var('zero') := 0;
aa_var('one') := 1;
aa_var('two') := 2;
Page 5 of 13
print_aa(aa_var);
END;
/
Result:
1 one
2 two
0 zero
Package Body
If a package specification declares cursors or subprograms, then a package body is
required; otherwise, it is optional. The package body and package specification must
be in the same schema.
Every cursor or subprogram declaration in the package specification must have a
corresponding definition in the package body. The headings of corresponding
subprogram declarations and definitions must match word for word, except for white
space.
Package Instantiation and Initialization
When a session references a package item, Oracle Database instantiates the package
for that session. Every session that references a package has its own instantiation of
that package. When Oracle Database instantiates a package, it initializes it.
Initialization includes whichever of the following are applicable:
• Assigning initial values to public constants
• Assigning initial values to public variables whose declarations specify them
• Executing the initialization part of the package body
Package State
The values of the variables, constants, and cursors that a package declares (in either
its specification or body) comprise its package state. If a PL/SQL package declares at
least one variable, constant, or cursor, then the package is stateful; otherwise, it is
stateless. Each session that references a package item has its own instantiation of
that package. If the package is stateful, the instantiation includes its state.
The package state persists for the life of a session, except in these situations:
• The package is SERIALLY_REUSABLE.
• The package body is recompiled.
If the body of an instantiated, stateful package is recompiled (either explicitly, with
the "ALTER PACKAGE Statement", or implicitly), the next invocation of a
subprogram in the package causes Oracle Database to discard the existing package
state and raise the exception ORA-04068.
After PL/SQL raises the exception, a reference to the package causes Oracle
Database to re-instantiate the package, which re-initializes it. Therefore, previous
changes to the package state are lost.
Page 6 of 13
SERIALLY_REUSABLE Packages
SERIALLY_REUSABLE packages let you design applications that manage memory
better for scalability. If a package is not SERIALLY_REUSABLE, its package state is
stored in the user global area (UGA) for each user. Therefore, the amount of UGA
memory needed increases linearly with the number of users, limiting scalability. The
package state can persist for the life of a session, locking UGA memory until the
session ends. In some applications, such as Oracle Office, a typical session lasts
several days.
If a package is SERIALLY_REUSABLE, its package state is stored in a work area in a
small pool in the system global area (SGA). The package state persists only for the
life of a server call. After the server call, the work area returns to the pool. If a
subsequent server call references the package, then Oracle Database reuses an
instantiation from the pool. Reusing an instantiation re-initializes it; therefore,
changes made to the package state in previous server calls are invisible.
Note:
Trying to access a SERIALLY_REUSABLE package from a database trigger, or from a
PL/SQL subprogram invoked by a SQL statement, raises an error.
Note:
If you make a mistake and depend on the value of a public variable that was set in a
previous work unit, then your program can fail. PL/SQL cannot check for such cases.
In below example, the bodiless packages pkg and pkg_sr are the same, except that
pkg_sr is SERIALLY_REUSABLE and pkg is not. Each package declares public variable n
with initial value 5. Then, an anonymous block changes the value of each variable to
10. Next, another anonymous block prints the value of each variable. The value of
pkg.n is still 10, because the state of pkg persists for the life of the session. The value
of pkg_sr.n is 5, because the state of pkg_sr persists only for the life of the
server call.
After the work unit (server call) of a SERIALLY_REUSABLE package completes, Oracle
Database does the following:
• Closes any open cursors.
• Frees some nonreusable memory (for example, memory for collection and long
VARCHAR2 variables)
• Returns the package instantiation to the pool of reusable instantiations kept for this
package.
END sr_pkg;
/
BEGIN
pkg.n := 10;
sr_pkg.n := 10;
END;
/
BEGIN
DBMS_OUTPUT.PUT_LINE('pkg.n: ' || pkg.n);
DBMS_OUTPUT.PUT_LINE('sr_pkg.n: ' || sr_pkg.n);
END;
/
Result:
pkg.n: 10
sr_pkg.n: 5
v_name people.name%TYPE;
BEGIN
IF sr_pkg.c%ISOPEN THEN
DBMS_OUTPUT.PUT_LINE('Cursor is open.');
ELSE
DBMS_OUTPUT.PUT_LINE('Cursor is closed; opening now.');
OPEN sr_pkg.c;
END IF;
FETCH sr_pkg.c INTO v_name;
DBMS_OUTPUT.PUT_LINE('Fetched: ' || v_name);
FETCH sr_pkg.c INTO v_name;
DBMS_OUTPUT.PUT_LINE('Fetched: ' || v_name);
END fetch_from_cursor;
/
Result:
Cursor is closed; opening now.
Fetched: John Smith
Fetched: Mary Jones
Cursor is open.
Fetched: Joe Brown
Fetched: Jane White
Page 10 of 13
Example 1, the declaration and definition of the cursor c1 are in the specification and
body, respectively, of the package emp_stuff. The cursor declaration specifies only
the data type of the return value, not the query, which appears in the cursor
definition.
Example 2, creates an API package and a helper package. Because of the ACCESSIBLE
BY clause in the helper package specification, only the API package can access the
helper package.
PROCEDURE h2 IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Helper procedure h2');
END;
END;
/
PROCEDURE p2 IS
BEGIN
DBMS_OUTPUT.PUT_LINE('API procedure p2');
helper.h2;
END;
END;
/
Result:
SQL> BEGIN
2 helper.h1;
3 END;
4/
helper.h1;
*
ERROR at line 2:
ORA-06550: line 2, column 3:
PLS-00904: insufficient privilege to access object HELPER
ORA-06550: line 2, column 3:
PL/SQL: Statement ignored
Page 13 of 13
For example, package STANDARD declares function ABS, which returns the absolute
value of its argument, as follows:
FUNCTION ABS (n NUMBER) RETURN NUMBER;
The contents of package STANDARD are directly visible to applications. You need not
qualify references to its contents by prefixing the package name.
For example, you might invoke ABS from a database trigger, stored subprogram,
Oracle tool, or 3GL application, as follows:
abs_diff := ABS(x - y);
If you declare your own version of ABS, your local declaration overrides the public
declaration. You can still invoke the SQL function by specifying its full name:
abs_diff := STANDARD.ABS(x - y);
Most SQL functions are overloaded. For example, package STANDARD contains these
declarations:
FUNCTION TO_CHAR (right DATE) RETURN VARCHAR2;
FUNCTION TO_CHAR (left NUMBER) RETURN VARCHAR2;
FUNCTION TO_CHAR (left DATE, right VARCHAR2) RETURN VARCHAR2;
FUNCTION TO_CHAR (left NUMBER, right VARCHAR2) RETURN VARCHAR2;
PL/SQL resolves an invocation of TO_CHAR by matching the number and data types
of the formal and actual parameters.
Disadvantages of Packages:
More memory may be required on the Oracle database server when using Oracle
PL/SQL packages as the whole package is loaded into memory as soon as any object
in the package is accessed.
Updating one of the functions/procedures will invalid other objects which use
different function/procedures since whole package need to be compiled.