Sunteți pe pagina 1din 32

PL/SQL

ISAD211 1
PL/SQL - Oracle's Procedural
Language extension to SQL
 loosely based on Ada
 includes (inter alia)
 block structure
 datatypes (including Boolean)
 variables & constants
 assignment statement
 conditional statements
 if .. then
 if .. then .. else
 if .. then .. elsif
 loops
 basic loop (needs exit condition)
 for loop
 while loop

 allows most SQL commands to be embedded


ISAD211 2
PL/SQL blocks
 anonymous blocks
 procedures
 functions

ISAD211 3
Anonymous block examples
BEGIN
DBMS_OUTPUT.PUT_LINE('Hello World!');
END;

DECLARE
v_day_of_week VARCHAR2(12); -- local variable
BEGIN
SELECT TO_CHAR(SYSDATE, 'Day')
INTO v_day_of_week
FROM sys.dual;
IF v_day_of_week IN ('Saturday', 'Sunday')
THEN
-- note use of extra quote in string
DBMS_OUTPUT.PUT_LINE('It''s the weekend!');
ELSE
DBMS_OUTPUT.PUT_LINE('Too bad - it''ll be the weekend
soon');
END IF;
END; SET SERVEROUTPUT ON
to get output from
ISAD211 DBMS_OUTPUT.PUT_LINE 4
Stored programs
 Codestored in the database and
executed on the server
 advantages of DB approach
 storeonce, use many
 backup/recovery
 access control

 Multiple
use by multiple
users/applications
GRANT EXECUTE ON <proc_name> TO <username>

ISAD211 5
Stored procedure
CREATE OR REPLACE PROCEDURE TGITW IS
v_day_of_week VARCHAR2(12); -- DECLARE not used here
BEGIN
SELECT TO_CHAR(SYSDATE, 'Day')
INTO v_day_of_week
FROM sys.dual;
IF v_day_of_week IN ('Saturday', 'Sunday') THEN
DBMS_OUTPUT.PUT_LINE('It''s the weekend!');
ELSE
DBMS_OUTPUT.PUT_LINE('Too bad - it''ll be the weekend soon');
END IF;
END;

-- SQL*Plus
exec TGITW

-- SQL*Plus and SQL Developer


BEGIN
TGITW;
END;

ISAD211 6
Stored function
CREATE OR REPLACE FUNCTION get_age
(p_birth_date IN DATE) -- INput parameter
RETURN INTEGER IS -- data type of result
v_age INTEGER;
BEGIN
SELECT TRUNC(MONTHS_BETWEEN(SYSDATE,
p_birth_date)/12)
INTO v_age
FROM sys.dual;
RETURN(v_age); -- result of function
END;

GRANT EXECUTE ON get_age TO PUBLIC;

SELECT sname, bdate, brian.get_age(bdate) age


FROM rearp.student
ISAD211 ORDER BY age DESC, bdate ASC; 7
Also available …
SELECT brian.valid_postcode('PL4 8AA')
FROM sys.dual;

TRUE

SELECT brian.valid_postcode('PL0 8AA')


FROM sys.dual;

FALSE

ISAD211 8
Cursors
 SQL query delivers an indivisible SET of
rows
 Cursor allows row by row processing of
the result set of a query
 Think of a cursor as a local table of
results
 Read one record or row at a time
 Do something with it

ISAD211 9
Cursor operations
 DECLARE
 specify query to populate cursor
 OPEN
 run query to populate cursor
 FETCH
 get a 'row' from the cursor
 CLOSE

ISAD211 10
DECLARE title_cur cursor
CURSOR title_cur IS
SELECT title
FROM books;

ISAD211 11
OPEN title_cur;

Serpent's Reach
Faded Sun, Kesrith, The
Faded Sun, Shon'jir, The

Titans, The
Black Tulip, The

ISAD211 12
FETCH title_cur INTO v_title;

Serpent's Reach
Faded Sun, Kesrith, The
Faded Sun, Shon'jir, The
v_title
… Serpent's Reach
Titans, The
Black Tulip, The

ISAD211 13
FETCH title_cur INTO v_title;

Serpent's Reach
Faded Sun, Kesrith, The
Faded Sun, Shon'jir, The
v_title
… Faded Sun, Kesrith, The
Titans, The
Black Tulip, The

ISAD211 14
FETCH title_cur INTO v_title;

Serpent's Reach
Faded Sun, Kesrith, The
Faded Sun, Shon'jir, The
v_title
… Faded Sun, Shon'jir, The
Titans, The
Black Tulip, The

ISAD211 15
FETCH title_cur INTO v_title;

Serpent's Reach
Faded Sun, Kesrith, The
Faded Sun, Shon'jir, The
v_title
… Titans, The
Titans, The
Black Tulip, The

ISAD211 16
FETCH title_cur INTO v_title;

Serpent's Reach
Faded Sun, Kesrith, The
Faded Sun, Shon'jir, The
v_title
… Black Tulip, The
Titans, The
Black Tulip, The

ISAD211 17
EXIT WHEN title_cur
%NOTFOUND;

Serpent's Reach
Faded Sun, Kesrith, The
Faded Sun, Shon'jir, The
v_title

Titans, The
Black Tulip, The

No rows left in cursor

ISAD211 18
Cursor example
DECLARE
v_new_title VARCHAR2(60);
v_title VARCHAR2(60);
v_length INTEGER;
v_char CHAR(1);
CURSOR c_title IS
SELECT title
FROM books;
BEGIN
OPEN c_title;
LOOP
FETCH c_title INTO v_title;
EXIT WHEN c_title%NOTFOUND;
v_length := LENGTH(v_title);
v_new_title := '';
FOR i IN 1..v_length LOOP
v_char := SUBSTR(v_title, i, 1);
IF UPPER(v_char) IN ('A', 'E', 'I', 'O', 'U')
THEN
v_char := '*';
END IF;
v_new_title := v_new_title||v_char;
END LOOP;
DBMS_OUTPUT.PUT_LINE(v_new_title);
END LOOP;
CLOSE c_title;
END;
ISAD211 19
Listing stored code in
SQL Developer

ISAD211 20
PL/SQL exception handling
 Enables‘bulletproofing’ of code to
handle run-time errors and retain
processing control

ISAD211 21
Example (modified from Oracle
documentation)

DECLARE
v_pe_ratio NUMBER(3,1);
BEGIN
SELECT price / earnings -- potential division-by-zero error
INTO v_pe_ratio
FROM stocks
WHERE symbol = 'XYZ';
INSERT INTO stats (symbol, ratio)
VALUES ('XYZ', v_pe_ratio);
COMMIT;
EXCEPTION -- exception handlers begin
WHEN ZERO_DIVIDE THEN -- handles 'division by zero' error
INSERT INTO stats (symbol, ratio) VALUES ('XYZ', NULL);
COMMIT;
WHEN OTHERS THEN -- handles all other errors
ROLLBACK;
END; -- exception handlers and block end here

ISAD211 22
Advantages
 Need to code multiple checks
removed
 A single exception handler will
process all errors of a given type

ISAD211 23
Some common pre-defined
PL/SQL exceptions
 INVALID_NUMBER
 conversion of a character string into a number fails
(ORA-01722)
 NO_DATA_FOUND
 A SELECT INTO statement returns no rows (ORA-
01403)
 VALUE_ERROR
 An arithmetic, conversion, truncation, or size-
constraint error occurs. For example, when your
program selects a column value into a character
variable, if the value is longer than the declared
length of the variable (ORA-06502)
 PROGRAM_ERROR
 PL/SQL has an internal problem (ORA-06501)

ISAD211 24
Database triggers revisited
coded in PL/SQL
critical for data integrity
server-side integrity ensures
more robust database than
client-side validation

ISAD211 25
Client-side integrity

integrity checks
application database

database is
ISAD211 vulnerable 26
Server-side integrity

integrity checks
application database

database is
ISAD211 protected 27
Issues
 Data sent to the server before being
checked for integrity increases network
traffic and server load
 Perform simple client-side 'belt and
braces' integrity checking, e.g. check
for required fields
 Opaque server error messages need to
be communicated sensibly to the
application/user

ISAD211 28
Server- & client-side integrity

integrity checks

integrity checks
application database

DB & network
ISAD211 load is reduced 29
Example trigger
CREATE OR REPLACE TRIGGER trg_clients
BEFORE INSERT OR UPDATE OF dob ON clients FOR EACH ROW
BEGIN
IF INSERTING THEN
SELECT seq_client_id.nextval
INTO :NEW.client_id
FROM sys.dual;
END IF;
IF MONTHS_BETWEEN(SYSDATE,:NEW.dob) < 18*12 THEN
/* Issue error code (ORA-20000) and message */
RAISE_APPLICATION_ERROR(-20000, 'Client must be at
least 18 years of age');
END IF;
END;

ISAD211 30
References
 PLSQL by Example on Portal

 PL/SQLUser's Guide and


Reference

 Oracle10g Database Error


Messages

ISAD211 31
Exercise
 Write a PL/SQL function (AVERAGE_PRICE) to
calculate the average retail price of books
(rounded to the nearest penny) in the
Harrington books table where the retail price is
above an amount specified as a parameter.
You should use a cursor.
 
 Test your results against
 
SELECT ROUND(AVG(retail_price),2)
FROM books
WHERE retail_price > &threshold
ISAD211 32

S-ar putea să vă placă și