18-1
Part 18:
Application Programming II
(Stored Procedures,Triggers)
References:
Oracle8 Application Developers Guide, Oracle Corporation, 1997, Part No. A58241-01.
PL/SQL Users Guide and Reference, Oracle Corporation, 1997, Part No. A58236-01.
Warning:
These slides are old (from 1999). Today, Java can be used as an alternative to PL/SQL.
Universit
at Halle, 2011
18-2
Objectives
You should know some advantages of using stored
procedures.
You should have at least some basic impression of
the Oracle PL/SQL syntax.
You should be able to explain what triggers are.
You should know some applications of triggers.
You should have some basic impression of the trigger syntax in Oracle.
Stefan Brass: Datenbanken I
Universit
at Halle, 2011
18-3
Overview
1. PL/SQL
2. Triggers in Oracle
Universit
at Halle, 2011
18-4
Introduction (1)
PL/SQL is an imperative programming language
with variables and the usual control structures.
PL/SQL has an especially good interface to SQL,
e.g. the same type system as the Oracle database.
Procedures written in PL/SQL can be stored and
executed on the database server.
PL/SQL is not meant for creating user interfaces.
However, it is used in other Oracle user interface products. All input/output must be done with parameters or database tables. E.g., if
a web page is created, it is first stored in the DB. It is a server-side
programming language.
Stefan Brass: Datenbanken I
Universit
at Halle, 2011
18-5
Introduction (2)
Advantages:
Instead of sending many SQL commands to the
server over the network, you send only a single call
to a procedure stored on the server.
So the network load is reduced as the data intensive computation is
done on the DB server and only the final result is sent to the client
where it is displayed.
Universit
at Halle, 2011
18-6
Introduction (3)
Natural Development:
DBMS were introduced to put the data of a company under central control:
to avoid redundancies and inconsistencies,
to share the data,
to simplify the development of new applications,
to simplify administration (data stored in a single
place).
Future DBMS should manage also procedures or
entire programs, not only data.
Stefan Brass: Datenbanken I
Universit
at Halle, 2011
18-7
Introduction (4)
A Subprogram-Library is not the Same:
Application programs and their dependencies (used
tables) are not in data dictionary.
If the DB schema is changed, problems are only discovered when the
corresponding application program is executed.
Universit
at Halle, 2011
18-8
Example (1)
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
(11)
(12)
(13)
CREATE PROCEDURE
Withdraw(acc number, amt number)
IS
b Account.Balance%TYPE;
-- b is a variable with the same type
-- as column Balance of table Account
BEGIN
SELECT Balance INTO b FROM Account
WHERE No=acc FOR UPDATE OF Balance;
IF b < amt THEN
INSERT INTO Rejected VALUES
(SYSDATE, acc, amt);
...
Universit
at Halle, 2011
18-9
Example (2)
(13)
(14)
(15)
(16)
(17)
(18)
(19)
(20)
(21)
Universit
at Halle, 2011
18-10
Lexical Syntax
The lexical syntax of PL/SQL (defining tokens /
word symbols) is intentionally very similar to SQL.
PL/SQL is case-insensitive, except in string literals.
And in delimited/quoted identifiers.
Universit
at Halle, 2011
18-11
Universit
at Halle, 2011
18-12
Universit
at Halle, 2011
18-13
Universit
at Halle, 2011
18-14
Declarations
The basic declaration syntax is hVariablei hTypei;:
current_balance NUMBER(8,2);
You can specify an intial value, else NULL is used:
emp_count PLS_INTEGER := 0;
You can forbid the assignment of null values:
zip_code CHAR(8) NOT NULL := PA 15260;
You can forbid any future assignments:
credit_limit CONSTANT NUMBER := 100.00;
Stefan Brass: Datenbanken I
Universit
at Halle, 2011
18-15
Universit
at Halle, 2011
18-16
Universit
at Halle, 2011
18-17
CREATE PROCEDURE
Withdraw(acc number,
amt number DEFAULT 60.00)
IS ...
Universit
at Halle, 2011
18-18
Universit
at Halle, 2011
18-19
CREATE PROCEDURE
Withdraw(acc IN NUMBER, amt IN NUMBER,
ok OUT BOOLEAN)
Universit
at Halle, 2011
18-20
Conditional Statements
An IF-statement in PL/SQL is written as follows:
IF hConditioni THEN
hSequence of Statementsi
ELSIF hConditioni THEN
hSequence of Statementsi
.
.
ELSE
hSequence of Statementsi
END IF;
The ELSIF- and ELSE-parts are optional.
Stefan Brass: Datenbanken I
Universit
at Halle, 2011
18-21
Universit
at Halle, 2011
18-22
Universit
at Halle, 2011
18-23
Universit
at Halle, 2011
18-24
Universit
at Halle, 2011
18-25
Universit
at Halle, 2011
18-26
CREATE PROCEDURE
raise_sal(no NUMBER, pct NUMBER) IS
BEGIN
UPDATE EMP
SET Sal := Sal * (1 + pct/100)
WHERE EmpNo = no;
INSERT INTO Sal_Development
SELECT SYSDATE, no, Sal
FROM Emp WHERE EmpNo = no;
END;
Universit
at Halle, 2011
18-27
Universit
at Halle, 2011
18-28
Cursors (1)
If a SELECT statement can return more than one row,
you need a cursor (or a special kind of FOR-Loop).
The cursor must be declared in the declaration section (the part before the BEGIN).
You specify an SQL query when you declare the cursor.
Universit
at Halle, 2011
18-29
Cursors (2)
Example: Create a web page containg the names
of all employees (using Oracles HTP package).
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
Universit
at Halle, 2011
18-30
Cursors (3)
(11)
(12)
(13)
(14)
(15)
(16)
(17)
(18)
(19)
(20)
(21)
(22)
(23)
htp.ulistOpen;
OPEN c;
LOOP
FETCH c INTO name;
EXIT WHEN c%NOTFOUND;
htp.listItem(name);
END LOOP;
CLOSE c;
htp.ulistClose;
htp.print(Generated: || SYSDATE);
htp.bodyClose;
htp.htmlClose;
END;
Universit
at Halle, 2011
18-31
Cursors (4)
Alternative (with WHILE-loop):
(12)
(13)
(14)
(15)
(16)
(17)
(18)
OPEN c;
FETCH c INTO name;
WHILE c%FOUND LOOP
htp.listItem(name);
FETCH c INTO name;
END LOOP;
CLOSE c;
Universit
at Halle, 2011
18-32
Cursors (5)
Alternative (with FOR-loop):
(12)
(13)
(14)
Universit
at Halle, 2011
18-33
Cursors (6)
For updates in loops, one can refer to CURRENT OF
hCursori in WHERE-conditions.
This requires a SELECT ... FOR UPDATE query.
Example: Suppose we want to assign a unique number to every instructor. We have used ALTER TABLE
to add a column No to the table Instructor, but it
first contains null values.
The following program also uses PL/SQLs recordtypes (which allow to store entire rows in a single
variable).
Stefan Brass: Datenbanken I
Universit
at Halle, 2011
18-34
Cursors (7)
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
(11)
(12)
Universit
at Halle, 2011
18-35
Cursors (8)
A cursor can have parameters, e.g.
(3)
(4)
(5)
OPEN c(20);
Universit
at Halle, 2011
18-36
Universit
at Halle, 2011
18-37
Universit
at Halle, 2011
18-38
Universit
at Halle, 2011
18-39
Universit
at Halle, 2011
18-40
Universit
at Halle, 2011
18-41
Universit
at Halle, 2011
18-42
Functions (1)
Functions are similar to procedures, but return a
value:
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
CREATE FUNCTION
factorial(n INTEGER) RETURN NUMBER
IS
i INTEGER;
f NUMBER := 1;
BEGIN
FOR i IN 1..n LOOP f := f * i;
END LOOP;
RETURN f;
END;
Universit
at Halle, 2011
18-43
Functions (2)
Functions can be used in PL/SQL expressions, e.g.
x := factorial(20) / 1000;
Functions can also be used in SQL queries (!):
SELECT n, factorial(n)
FROM
test_inputs
Functions are not allowed to have side effects.
Functions must execute a RETURN statement, or the
exception PROGRAM_ERROR is raised.
RETURN; (without value) can be used in procedures
to transfer the control back to the caller.
Stefan Brass: Datenbanken I
Universit
at Halle, 2011
18-44
Packages (1)
PL/SQL has a module mechanism.
You can define Packages which can contain declarations of types, procedures, functions, global
variables, constants, cursors, and exceptions.
The interface (public part) and the implementation
(private part) are defined separately.
Global variables persist for the duration of a session.
Across transactions. But remote calls are restricted.
Universit
at Halle, 2011
18-45
Packages (2)
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
(11)
(12)
Universit
at Halle, 2011
18-46
Universit
at Halle, 2011
18-47
Universit
at Halle, 2011
18-48
Universit
at Halle, 2011
18-49
You can also use an anonymous PL/SQL block inside C for computations which can be done simpler
in PL/SQL (but C with standard SQL is portable).
You can use host variables (C variables) in PL/SQL
whereever a PL/SQL variable would be allowed.
As usual, host variables must be marked with a colon.
Stefan Brass: Datenbanken I
Universit
at Halle, 2011
18-50
Universit
at Halle, 2011
18-51
Overview
1. PL/SQL
2. Triggers in Oracle
Universit
at Halle, 2011
18-52
Triggers (1)
Triggers are ECA (Event, Condition, Action) rules:
If a triggering event occurs,
E.g. an insertion on a certain table.
an action is done.
E.g. the tuple is inserted also in another table regularly checked
by the department head.
Thus, triggers are basically procedures that are implicitly called by the usual database commands.
This is a kind of hook for own code to extend the DB.
Stefan Brass: Datenbanken I
Universit
at Halle, 2011
18-53
Triggers (2)
Typical applications of triggers are:
Enforcement of complex integrity constraints.
Of course, if a constraint can be specified declaratively in the
CREATE TABLE statement, that is much better.
Propagation of updates to redundant data structures (e.g. materialized views, derived columns).
Enforcement of complex authorizations.
Enforcement of complex business rules.
Oracle also has INSTEAD OF trigger to define what
should happen if a user tries to updates a view that
would normally not be updatable.
Stefan Brass: Datenbanken I
Universit
at Halle, 2011
18-54
Universit
at Halle, 2011
18-55
Since Oracle 8i, it is also possible to react on system events (STARTUP, SHUTDOWN, SERVERERROR) client events (LOGON, LOGOFF), and DDL commands
(CREATE, ALTER, DROP).
There are event attribute functions to access more data for these
events.
Universit
at Halle, 2011
18-56
Universit
at Halle, 2011
18-57
Example (1)
Suppose we have a table
Inventory
ItemNo ItemName Stock MinStock Reordered
.
.
.
.
.
.
.
.
.
.
Our application programs change this table by
UPDATE Inventory SET Stock = Stock - :taken
WHERE ItemNo = :no
If the Stock becomes smaller than MinStock, we
want to automatically reorder the part.
Stefan Brass: Datenbanken I
Universit
at Halle, 2011
18-58
Example (2)
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
(11)
Universit
at Halle, 2011
18-59
Syntax (1)
Event:
The triggering event is specified by
(2)
(3)
Universit
at Halle, 2011
18-60
Syntax (2)
Condition:
When the triggering event occurs, the condition is
checked:
(4)
(5)
Universit
at Halle, 2011
18-61
Syntax (3)
Condition, continued:
If there is a name conflict with the tuple variables
new and old, one can use
REFERENCING new AS myNew
This must be written before FOR EACH ROW.
Universit
at Halle, 2011
18-62
Syntax (4)
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
(11)
(12)
(13)
Universit
at Halle, 2011
18-63
Syntax (5)
Action:
The action part is any PL/SQL block.
A PL/SQL block has the general form
(1)
(2)
(3)
(4)
(5)
(6)
(7)
DECLARE
... -- Declarations
BEGIN
... -- PL/SQL Statements
EXCEPTION
... -- Exception handlers
END;
Universit
at Halle, 2011
18-64
Syntax (6)
Action, continued:
COMMIT or ROLLBACK is not allowed in the PL/SQL
block (trigger action).
However, one can call the procedure
raise_application_error(error_number, message)
to abort the SQL command which fired the trigger.
One can select any error number between 20000 and 20999.
Universit
at Halle, 2011
18-65
Syntax (7)
Action, continued:
In row triggers, you can use the variables :new and
:old, which contain the tuple before and after the
command.
You cannot access the affected tuples in statement triggers. Note
that in the WHEN condition, old and new are written without :.
Universit
at Halle, 2011
18-66
Second Example
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
(11)
Universit
at Halle, 2011
18-67
Universit
at Halle, 2011