Procedures Stored in The Schema PL/SQL
Procedures Stored in The Schema PL/SQL
Procedures Stored in The Schema PL/SQL
PL/SQL
Why PL/SQL?
• Database vendors usually provide a procedural language as an
extension to SQL.
– PL/SQL (ORACLE)
– Microsoft SQL Server, Sybase provide their languages – similar to
PL/SQL
END;
/
Variable Declaration
Section (local variables).
Stored Functions
Syntax to create a stored function:
CREATE [OR REPLACE] FUNCTION function_name
[(parameter1 MODE DATATYPE [DEFAULT expression],
parameter2 MODE DATATYPE [DEFAULT expression],
…)] RETURN DATATYPE
AS
• If you omit it mode it will implicitly be IN.
[variable1 DATATYPE;
• In the header, the RETURN DATATYPE is part of the
variable2 DATATYPE; …] function declaration and it is required. It tells the
BEGIN compiler what datatype to expect when you invoke the
function.
statements
• RETURN inside the executable section is also required.
RETURN expression;
• If you miss the the RETURN clause in the declaration,
END; the program won’t compile.
/ • On the other hand, if you miss the RETURN inside the
body of the function, the program will execute but at
runtime Oracle will give the error ORA-06503: PL/SQL:
Function returned without a value.
Dropping, viewing stored programs
DROP PROCEDURE add_book;
SELECT text
FROM User_source
WHERE name = 'ADD_BOOK'
ORDER BY line;
• Observe that the name of the procedure or function is stored in upper
case.
Conditional logic –IF statement
IF condition1 THEN
statements
[ELSIF condition2 THEN] Comments
statements • The end of the IF statement is
[ELSE “END IF;” with a space in
last_statements] between.
END IF;
• The “otherwise if” is ELSIF not
ELSEIF
Examples
IF hourly_wage < 10 THEN
• You can put parenthesis around
boolean expression after the IF
hourly_wage := hourly_wage * 1.5;
and ELSIF but you don’t have
ELSE to.
hourly_wage := hourly_wage * 1.1;
• You don’t need to put {, } or
END IF;
BEGIN, END to surround
several statements between IF
IF salary BETWEEN 10000 AND 40000 THEN
and ELSIF/ELSE, or between
bonus := 1500; ELSIF/ELSE and END IF;
ELSIF salary > 40000 AND salary <= 100000
THEN bonus := 1000;
ELSE bonus := 0;
END IF;
Conditional logic –Simple CASE statement
CASE selector CREATE OR REPLACE PROCEDURE
WHEN expression_1 THEN statements PrintQualification(grade IN CHAR) AS
[WHEN expression_2 THEN statements] BEGIN
[ELSE statements] CASE grade
WHEN 'A' THEN
END CASE; dbms_output.put_line('Excellent');
• selector can be an expression of WHEN 'B' THEN
any datatype, and it provides the dbms_output.put_line('Very Good');
WHEN 'C' THEN
value we are comparing.
dbms_output.put_line('Good');
• expression_n is the expression to WHEN 'D' THEN
test for equality with the selector. dbms_output.put_line('Fair');
WHEN 'F' THEN
• If no WHEN matches the selector dbms_output.put_line('Poor');
value, then the ELSE clause is ELSE dbms_output.put_line('No such
executed. grade');
END CASE;
• If there is no ELSE clause PL/SLQ END;
will implicitly supply: /
ELSE RAISE
BEGIN
CASE_NOT_FOUND; which will PrintQualification('B');
terminate the program with an error END;
(if the program ends up in the ELSE /
clause).
Iterative Control: LOOP and EXIT Statements
• Three forms of LOOP statements: E.g. We wish to categorize salaries
according to their number of digits.
• LOOP, CREATE OR REPLACE FUNCTION
• WHILE-LOOP, and SalDigits(salary INT) RETURN INT
AS
• FOR-LOOP. digits INT := 1;
temp INT := salary;
• LOOP: The simplest form of LOOP BEGIN
statement is the basic (or infinite) LOOP
loop: temp := temp / 10;
LOOP
IF temp = 0 THEN
statements EXIT;
END IF;
END LOOP; --Or we can do: EXIT WHEN temp = 0
• You can use an EXIT statement to digits := digits + 1;
complete the loop. END LOOP;
RETURN digits;
• Two forms of EXIT statements: END;
/
• EXIT and
• EXIT WHEN. BEGIN
dbms_output.put_line(SalDigits(150000));
END;
/
WHILE-LOOP
E.g. We wish to categorize salaries
WHILE condition according to their number of digits.
LOOP CREATE OR REPLACE FUNCTION
statements SalDigits(salary INT) RETURN INT
END LOOP; AS
digits INT := 1;
temp INT := salary;
BEGIN
RETURN digits;
END;
/
BEGIN
dbms_output.put_line(SalDigits(150000));
END;
/
FOR Loops
• FOR loops iterate over a specified range of integers.
Comments
The range is evaluated when the FOR loop is first
entered and is never re-evaluated.
By default, iteration proceeds upward from the lower
bound to the higher bound. However, if you use the
keyword REVERSE, iteration proceeds downward from
the higher bound to the lower bound.
Nevertheless, you write the range bounds in ascending
(not descending) order.
Inside a FOR loop, the loop counter can be referenced
like a constant but cannot be assigned values.
An Example
• Let’s build a system that will assist
CREATE TABLE books (
in the cataloging and searching of isbn VARCHAR2(13) PRIMARY KEY,
library books. title VARCHAR2(200),
• For now, we’d like to address two summary VARCHAR2(2000),
author VARCHAR2(200),
requirements:
date_published DATE,
1. Allow the creation of catalog page_count NUMBER
entries for each newly );
acquired book.
2. Provide means of counting CREATE TABLE book_copies (
how many copies of a barcode_id VARCHAR2(100) PRIMARY
KEY,
particular book the library
isbn VARCHAR2(13) REFERENCES
owns. books(isbn)
• A simple E/R schema would be: );
favorite_play_title books.title%TYPE;
publication_date DATE;
CURSOR bcur IS
SELECT title, date_published
FROM books
WHERE UPPER(author) LIKE
'SHAKESPEARE%';
BEGIN
OPEN bcur;
LOOP
FETCH bcur INTO favorite_play_title,
publication_date;
EXIT WHEN bcur%NOTFOUND;
BEGIN
We can test this function as:
IF isbn_in IS NOT NULL THEN
OPEN bc_cur;
set serveroutput on
FETCH bc_cur INTO number_of_copies;
DECLARE
how_many INT;
CLOSE bc_cur;
END IF;
BEGIN
dbms_output.put_line(
RETURN number_of_copies;
'Number of copies of 1-56592-335-9: ' ||
END;
book_copy_qty('1-56592-335-9'));
/
END;
/