Beruflich Dokumente
Kultur Dokumente
To examine how a stored PL/SQL package can enhance application development and
performance
explain the concept of a PL/SQL package and identify the advantages of using
such a package
describe how a PL/SQL package is created and how packaged objects are executed
explain how a PL/SQL composite datatype can be stored in a package and passed
as a parameter to a packaged procedure or function
explain how Oracle supports the overloading of PL/SQL subprogram names
explain how Oracle uses the standard package to define the PL/SQL environment
PL/SQL objects can be encapsulated into a single stored program unit called a
PL/SQL package.
A PL/SQL package can contain both functions and procedures.
In fact, a package can contain any of these PL/SQL objects:
function
procedure
constant
variable
cursor
exception
A PL/SQL package can enhance Oracle application development in a number of
ways:
enhanced modularity
information hiding
persistent data
improved performance
A PL/SQL package enhances program modularity by encapsulating related
procedures, functions, and other objects into a single named PL/SQL package.
You can think of a PL/SQL package as a "library" of functional objects.
For example, a package can contain all the objects needed to process student
information.
Or a package can contain all the objects needed to process student loans.
A package allows information hiding by specifying objects as public or private.
A public package object can be executed by any calling program.
But a private package object is known only within the scope of the defining
package.
Information hiding allows easier application maintenance because a package can be
changed without changing the application programs that use the package, provided
the interface remains the same.
Public package variables and cursors are retained for the duration of the session
and can be referenced by any application.
This is called persistent data.
A PL/SQL package can improve application performance.
When a package object is first called, the entire package is loaded into memory.
And any application can call any object in the package without needing disk I/O to
reload the package into system memory.
A PL/SQL package is not a subprogram.
A package cannot be "executed".
It cannot be passed parameters and it cannot return a value.
But the individual objects within a PL/SQL package can be called or executed by
front-end application tools.
In addition to creating and using your own PL/SQL packages, you can use the
objects contained in pre-defined packages supplied by Oracle.
Packages can significantly improve the speed and quality of application
development.
But package design, creation, and maintenance must be carried out in a structured
manner.
And it is particularly important that packages are properly documented and tested.
The DBA should ensure that proper procedures are established and followed.
Like a procedure or function, a PL/SQL package is declared in two parts:
specification
body
Here is the basic syntax for a package specification.
The CREATE PACKAGE keywords are used to create the package specification.
And the "owning" schema is specified along with the package name:
schema.package_name
Multiple public objects such as functions and procedures can be declared.
A user can call a public packaged object provided he or she has EXECUTE privilege
on the package.
Here is the basic syntax for a package body.
This is how a packaged object is called from within a PL/SQL block or subprogram.
But the user does not need table level privileges because the privileges of the
package owner are granted implicitly for the duration of the execution of the called
object.
Application development can be standardized and modularized by declaring
composite datatypes as public objects in a PL/SQL package.
You can code a TYPE declaration for a user-defined RECORD or TABLE datatype as a
public packaged object.
And then declare instances of that datatype in multiple application programs
throughout the Oracle environment.
You don't need to code a TYPE declaration in each application that uses the
packaged datatype.
Developers can create a "library" package of datatype declarations that can be
reused in any application.
A PL/SQL package can be changed without recompiling the applications that use the
package's objects.
Here is an example package specification that declares two user-defined datatypes
as public packaged objects.
A package body is not needed because all the package contents are datatypes.
Once the package has been created and stored in the database, instances of the
user-defined datatypes can be declared in any application.
Here is an example PL/SQL block that declares an instance of the student_record
datatype.
And then populate and pass the RECORD fields into another packaged procedure as
actual parameters.
The called packaged procedure appdev.maintain can also declare an instance of the
user-defined RECORD by calling the appdev.records package.
The important point to remember is that you can use a package to contain a data
structure declaration.
And you can reuse that data structure anywhere in the Oracle environment without
having to recode the declaration.
Oracle allows the same subprogram name to be used for more than one PL/SQL
packaged subprogram, provided the formal parameters are different.
This concept is called overloading.
Overloading can be used to allow a single call to access multiple functions and
procedures.
For example, a PL/SQL package can contain a procedure that accepts a VARCHAR2
formal parameter.
And the same package can contain a second procedure of the same name that
accepts a NUMBER formal parameter.
Oracle resolves overloading by comparing the actual parameters supplied at runtime with the formal parameters declared in the packaged subprograms.
Here is an example package that contains two procedures called del_stu.
If del_stu is called and has passed a VARCHAR2 parameter, the first procedure will
execute.
And if del_stu is passed a NUMBER parameter, the second procedure will execute.
Overloading works only if the formal parameters in each subprogram differ in
number, order, or datatype.
Subtypes of datatype NUMBER are not considered different for the purpose of
overloading subprogram names.
Oracle7 uses a package called standard to define the PL/SQL environment.
The standard package declares datatypes, exceptions, functions, and procedures.
All declarations in the standard package are public and are globally visible to all
applications and users.
This means that any object declared in the standard package is available to any tool
in the Oracle environment that supports PL/SQL.
For example, the no_data_found exception is declared in the standard package.
And it can be used by any PL/SQL program.
SQL*Plus functions such as TO_NUMBER and DECODE are also declared in the
standard package.
The standard package is created by the DBA by running a script file called
standard.sql.
The script that creates the standard package is usually stored in the
\oracle\rdbms\admin directory.
Once it is created, the standard package is stored in parsed format in the database.
The standard package is like any other stored PL/SQL package.
When a user calls a packaged object, the package is loaded and held "resident" in
memory.
Another user can use an object in the package without causing disk I/O.
Here is an extract from the script used to create the standard package.
Be careful not to declare a function or procedure with the same name as an object
in the standard package.
If you do, the local declaration will override the global declaration and the core
functionality of PL/SQL may be affected.
A number of other packages are also supplied with Oracle7.
These packages contain procedures and functions that can assist the efficient
development and administration of the database.
The dbms_output package is particularly useful in debugging applications.
For example, you can output variable values to screen.
UNIT 2
You will now develop a sample PL/SQL package and calling program.
Here is the specification for the sample package and calling program.
To begin, let's examine what the package and calling program should do logically.
The package should contain a public function that accepts a RECORD datatype as a
formal parameter and inserts a new row in the student table.
And the function should return a value to the calling program to indicate whether a
row was successfully inserted.
The package should also contain a public procedure that accepts a social security
number as a parameter and deletes a row from the student table.
And finally, the calling program should call and pass parameters to the packaged
function to create a new student.
That's what the program should do logically.
The next step is to code the package specification.
The specification should declare the function and procedure as public packaged
objects.
Remember, a calling program has access only to public packaged objects declared
in the package specification.
To begin the specification, a CREATE statement should be coded.
Next, a RECORD datatype is declared to hold the student details.
Next, an IF statement should be coded to call the function and pass in the actual
parameters.
That's the end of the calling program.
Here is the run-time output generated if the insert was carried out successfully.
Look at how PL/SQL substitutes the run-time values entered by the user for the
declared substitution variables.
For example, it can fire to prevent a user or application from updating base table
data outside authorized times.
A database trigger has three parts:
event
restriction
body
A trigger event specifies the table name and the DML statement(s) that cause a
database trigger to fire.
For example, you can specify an INSERT statement on the student table as a trigger
event.
And when that event occurs, the trigger will fire.
A single trigger can have multiple trigger events.
But a trigger's events can only specify a single table.
A trigger restriction is an optional boolean PL/SQL expression that can be used only
with a particular type of database trigger called a ROW trigger.
It is evaluated to determine whether to continue firing a trigger.
A restriction can be omitted, in which case the trigger will be fired every time the
trigger event occurs.
A trigger body contains the executable statements that are carried out when the
trigger is fired.
A trigger body is like any PL/SQL block.
It can have a declare section, a procedure section, and an exception section.
A database trigger is created and stored using the CREATE TRIGGER statement.
Here is the basic syntax required to create a database trigger.
You must be granted the appropriate privilege by the DBA to successfully create a
database trigger.
The privilege CREATE TRIGGER allows you to create a trigger in your schema.
And CREATE ANY TRIGGER allows you to create a trigger in another schema.
A user or application does not require privileges on a database trigger or on any
tables accessed by a trigger.
The privileges of the schema that "owns" the trigger are implicitly granted for the
duration of the execution of the trigger.
A trigger can fire before or after a DML operation.
A BEFORE trigger is fired before the triggering DML statement is executed.
So, it can be used to determine whether to abort the triggering statement.
It can also be used to derive values before an INSERT or UPDATE statement is
executed.
An AFTER trigger is fired after the triggering DML statement has executed.
It can be used to enforce integrity constraints or log DML activity.
A trigger can fire on INSERT, UPDATE, or DELETE statements.
And a trigger can fire at ROW level or at STATEMENT level.
In all, there are twelve possible triggering events for each table.
In general, an AFTER trigger makes better use of memory and causes less
performance overhead than a BEFORE trigger.
Oracle supports a ROW database trigger.
Like a STATEMENT trigger, a ROW trigger can be created to fire before or after a
DML statement.
And a ROW trigger event can be specified to fire on UPDATE, INSERT, or DELETE.
But a ROW trigger fires once for each row affected by a triggering statement, while
a STATEMENT trigger fires just once.
Here is an example of an AFTER DELETE ROW trigger that fires when the event
"after delete on student" occurs.
The keywords FOR EACH ROW specify that the trigger fires for each row affected by
the triggering event.
Remember, Oracle creates a STATEMENT trigger by default if the keywords FOR
EACH ROW are omitted.
The trigger body IF statement will insert a row in the debts_outstanding table after
each row is deleted, provided the deleted loan_amount is greater than zero.
Look again at the IF statement condition in the example ROW trigger.
This code uses a notation called a correlation name.
It can be used in a ROW trigger to reference a data element that is in the process of
mutating.
In this case, the correlation name OLD references data in a row that has just been
logically deleted by the triggering statement.
And loan_amount references the base table column in the "deleted" row.
A correlation name is preceded by a colon (:), unless it is used in a trigger
restriction.
You can reference a deleted row in a trigger using the correlation name OLD
because the deletion has not yet been committed to the database.
Think about what happens at run-time.
This statement causes all the rows in the student table to be deleted.
And after each row is deleted, the example trigger fires once.
If the value of :OLD.loan_amount in the logically deleted row is greater than zero,
the trigger inserts a row in the debts_outstanding table.
In an INSERT ROW trigger there is no old value, but you can use the NEW correlation
name to refer to an inserted data element: :NEW.column_name
In an UPDATE ROW trigger you can use both the OLD and NEW correlation names to
compare data values before and after the update, for example IF
(:OLD.column_name > :NEW.column_name) THEN...
In a DELETE ROW trigger, there is no new value, so only the OLD correlation name
can be used.
Oracle does not support correlation names in a STATEMENT trigger.
Oracle allows the default correlation names to be renamed using this syntax in the
ROW trigger event: REFERENCING [NEW | OLD] AS REFERENCE_NAME
Here is an example of a trigger that uses referencing to "rename" the correlation
names OLD and NEW.
The trigger condition can be any valid boolean PL/SQL expression, but cannot
include a query.
Look now at this example AFTER UPDATE ROW trigger that uses a restriction.
The loan_amount column in the student table has been specified in the trigger
event.
This means that the trigger will fire only if data in that column is affected by an
UPDATE statement.
You can specify more than one base table column in an UPDATE trigger event.
If you omit a column reference, the trigger will fire when any column in the table is
affected by a triggering DML statement.
The trigger event specifies that the trigger will fire before an INSERT, UPDATE, or
DELETE statement is executed on the student table.
If you decide to disable a base table trigger for the duration of a data load, it is
important that another method is used to validate the data.
The DBA only should decide whether a trigger should be disabled.
Triggers on a table can be re-enabled using the ENABLE keyword.
You can delete a trigger from the database using this syntax: DROP TRIGGER
trigger_name;
When a trigger is created, the source code is stored in the database.
You can examine source code and other trigger details by querying these default
views:
user_triggers
dba_triggers
all_triggers
Here is the data definition of the user_triggers view.
This SELECT statement retrieves information on the triggers in the active schema.
The DBA can examine details of any trigger by using the views dba_triggers and
all_triggers.
UNIT 4
You will now develop a sample database trigger.
The trigger should insert a row in the grade_trans_log table whenever a row is
deleted from the grade table.
The purpose of this trigger is to maintain a transaction log.
The sample trigger should be created on the grade table.
The most appropriate trigger to use here is an AFTER DELETE ROW trigger.
An AFTER trigger is generally more efficient than a BEFORE trigger because a single
database call is generated.
A ROW trigger is generally more useful than a STATEMENT trigger because it can fire
once for each row affected by the triggering statement.
The first step in creating the sample trigger is to name the trigger grade_trigger.
Correlation names should be used in the VALUES clause of the INSERT statement to
reference each row as it is deleted from the grade table.
The correlation name OLD refers to the row that has just been logically deleted by
the triggering statement.
The trigger code can be saved as a script and executed at the SQL> prompt to
create and store the trigger in the database.
This SQL statement causes four rows to be deleted from the grade table.
The triggering statement deletes four rows and causes the trigger event "after
delete on grade".
So the trigger is fired four times, once for each row affected by the triggering
statement.
A SELECT statement on the grade_trans_log table verifies that the trigger fired
successfully.