0% found this document useful (0 votes)
8 views

I3306 Chapter5

This document provides an outline for a chapter on PL/SQL and SQL that will be covered in a Database II course. The chapter outline includes sections on PL/SQL syntax, data types, variables, control statements, subprograms, cursors, records, error handling, triggers, packages, and collections. An introductory section provides an overview of PL/SQL including its main features and what PL/SQL is.

Uploaded by

Elias Khoury
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

I3306 Chapter5

This document provides an outline for a chapter on PL/SQL and SQL that will be covered in a Database II course. The chapter outline includes sections on PL/SQL syntax, data types, variables, control statements, subprograms, cursors, records, error handling, triggers, packages, and collections. An introductory section provides an overview of PL/SQL including its main features and what PL/SQL is.

Uploaded by

Elias Khoury
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 102

I3306 – Database II

Chapter 5 - Procedural Language /


Structured Query Language

References
http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/toc.htm
Chapter Outline
• Overview of PL/SQL
• PL/SQL Basic Syntax
• Data Types, Variables and Operators
• Control Statements
• Subprograms: Procedures, Functions
• Cursors
• Records
• Error-Handling, Exceptions
• Triggers
• Packages
• Collections

Dr Michel Nabaa PL/SQL 2


Overview of PL/SQL

• What is PL/SQL
• Main Features of PL/SQL

Dr Michel Nabaa PL/SQL 3


What is PL/SQL

• The Oracle procedural extension of SQL


• PL/SQL combines the data-manipulating power of
SQL with the processing power of procedural
languages.
• PL/SQL is one of three key programming languages
embedded in the Oracle Database, along with SQL
itself and Java
• Developed by Oracle corporation in the early 90s.

Dr Michel Nabaa PL/SQL 4


Main Features of PL/SQL
• PL/SQL is tightly integrated with SQL.
• It offers extensive error checking.
• It offers numerous data types.
• It offers a variety of programming structures.
• It supports structured programming through
functions and procedures.
• It supports object-oriented programming.
• It supports the development of web applications
and server pages.
Dr Michel Nabaa PL/SQL 5
PL/SQL Basic Syntax

• Block
• Identifiers
• Delimiters
• Comments

Dr Michel Nabaa PL/SQL 6


PL/SQL Bloc
• PL/SQL is a block-structured language.
• PL/SQL programs are composed of logical blocks of
code.
• Each block consists of three sections: declaration,
executable and exception
DECLARE Optional
<declarations section> Variables, cursors, user-defined exceptions
BEGIN Mandatory
<executable command(s)> SQL statements, PL/SQL statements
EXCEPTION Optional
<exception handling> Actions to perform when errors occur
END;
Dr Michel Nabaa PL/SQL 7
PL/SQL Bloc
DECLARE
message varchar2(20):= 'Hello, World!';
BEGIN
dbms_output.put_line(message);
END;
/

Output
Hello, World!
PL/SQL procedure successfully completed.

Dr Michel Nabaa PL/SQL 8


PL/SQL Bloc

• PL/SQL blocks can be nested


– An executable section (BEGIN … END) can
contain nested blocks.
– An exception section can contain nested blocks.
• PL/SQL blocks can be labeled.
• A label given to a block is called qualifier.

Dr Michel Nabaa PL/SQL 9


PL/SQL Bloc
BEGIN <<outer>>
DECLARE
v_outer_variable VARCHAR2(20):='GLOBAL VARIABLE';
BEGIN
DECLARE
v_inner_variable VARCHAR2(20):='LOCAL VARIABLE';
BEGIN
DBMS_OUTPUT.PUT_LINE(v_inner_variable);
DBMS_OUTPUT.PUT_LINE(v_outer_variable);
END;
DBMS_OUTPUT.PUT_LINE(v_outer_variable);
END;
END outer;

Dr Michel Nabaa PL/SQL 10


PL/SQL identifiers

• Identifiers are used to name PL/SQL program items


and units, such as constants, variables, exceptions,
and subprograms.
• An identifier consists of a letter optionally followed by
more letters, numerals, dollar signs, underscores, and
number signs #.
• An identifier should not exceed 30 characters
• Identifiers are not case sensitive.
• A reserved word cannot be used as an identifier.

Dr Michel Nabaa PL/SQL 11


PL/SQL Delimiters
• A delimiter is a symbol with a special meaning.
Delimiter Description
+, -, *, / Addition, subtraction/negation, multiplication, division
% Attribute indicator
' Character string delimiter
. Component selector
(,) Expression or list delimiter
: Host variable indicator
, Item separator
" Quoted identifier delimiter
= Relational operator
@ Remote access indicator
; Statement terminator
:= Assignment operator
=> Association operator
|| Concatenation operator
** Exponentiation operator
<<, >> Label delimiter (begin and end)

/*, */ Multi-line comment delimiter (begin and end)

-- Single-line comment indicator


.. Range operator
<, >, <=, >= Relational operators
<>, '=, ~=, ^= Different versions of NOT EQUAL

Dr Michel Nabaa PL/SQL 12


PL/SQL Comments
• PL/SQL supports single-line and multi-line comments.
• All characters available inside any comment are ignored by the
PL/SQL compiler.
• The PL/SQL single-line comments start with the delimiter –
• multi-line comments are enclosed by /* and */.

DECLARE
-- variable declaration
message varchar2(20):= 'Hello, World!';
BEGIN
/*
* PL/SQL executable statement(s)
*/
dbms_output.put_line(message);
END;
Dr Michel Nabaa / PL/SQL 13
PL/SQL Data Types
Scalar : Single values with no internal components, such as
a NUMBER, DATE, or BOOLEAN.

Large Object (LOB) : Pointers to large objects that are stored


separately from other data items, outside the table, such as text,
graphic images, video clips, and sound waveforms.

Composite : Data items that have internal components that can


be accessed individually. For example, collections and records.

Reference : Pointers to other data items.

Dr Michel Nabaa PL/SQL 14


PL/SQL Scalar Data Types
• A scalar data type can have subtypes.
• A subtype is a data type that is a subset of another data type,
which is its base type.
• A subtype has the same valid operations as its base type.
• PL/SQL predefines many types and subtypes in the package
STANDARD and lets you define your own subtypes.

• The PL/SQL scalar data types are:


– The SQL data types with different maximum sizes
– BOOLEAN
– PLS_INTEGER, BINARY_INTEGER are identical
– REF CURSOR
– User-defined subtypes

Dr Michel Nabaa PL/SQL 15


PLS_INTEGER Data Type
• The PLS_INTEGER data type stores signed integers in the range -
2,147,483,648 through 2,147,483,647, represented in 32 bits.
• Advantages of PLS_INTEGER data type over the NUMBER data type and
NUMBER subtypes:
– PLS_INTEGER values require less storage.
– PLS_INTEGER operations use hardware arithmetic, so faster than
NUMBER operations.

• Predefined PLS_INTEGER Subtypes


NATURAL Nonnegative PLS_INTEGER value

NATURALN Nonnegative PLS_INTEGER value with NOT NULL constraint

POSITIVE Positive PLS_INTEGER value

POSITIVEN Positive PLS_INTEGER value with NOT NULL constraint

SIGNTYPE PLS_INTEGER value -1, 0, or 1 (useful for programming tri-state logic)

SIMPLE_INTEGER PLS_INTEGER value with NOT NULL constraint

Dr Michel Nabaa PL/SQL 16


User-Defined PL/SQL Subtypes
• PL/SQL lets you define your own subtypes.

– Unconstrained Subtypes
An unconstrained subtype has the same set of values as its base type, so it is
only another name for the base type
subtype "double precision" is float

– Constrained Subtypes
A constrained subtype has only a subset of the values of its base type.

SUBTYPE subtype_name IS base_type


{ precision [, scale ] | RANGE low_value .. high_value } [ NOT NULL ]

SUBTYPE Balance_type IS NUMBER(8,2);


v_checking_account Balance_type;
SUBTYPE Under_100_type IS PLS_INTEGER RANGE 0..99;
v_under100 Under_100_type;

Dr Michel Nabaa PL/SQL 17


PL/SQL Variables
• Variable Declaration
variable_name [CONSTANT] datatype [NOT NULL] [:= | DEFAULT initial_value]

DECLARE
v_sales number(10, 2);
c_pi CONSTANT double precision := 3.1415;
v_name varchar2(25);
v_greetings varchar2(20) DEFAULT 'Have a Good Day';

• Variable Scope
PL/SQL allows the nesting of blocks
Local variables − Variables declared in an inner block and not accessible to outer
blocks.
Global variables − Variables declared in the outermost block or a package.

Dr Michel Nabaa PL/SQL 18


PL/SQL Variables
• Variables can be declared with the same name in two different
blocks (nested blocks).

• A variable declared within an inner block is not accessible to the


outer block.

• A variable declared in an outer block, is also accessible to all


nested inner blocks unless a variable with the same name is
declared in the current inner block. In such a case prefix the
variable with the qualifier of its bloc.

Dr Michel Nabaa PL/SQL 19


PL/SQL Variables
BEGIN <<outer>>
DECLARE
v_father_name VARCHAR2(20):='Patrick';
v_date_of_birth DATE:='20-Apr-1972';
BEGIN
DECLARE
v_child_name VARCHAR2(20):='Mike';
v_date_of_birth DATE:='12-Dec-2002';
BEGIN
DBMS_OUTPUT.PUT_LINE('Father''s Name: '||v_father_name);
DBMS_OUTPUT.PUT_LINE('Date of Birth: '||outer.v_date_of_birth);
DBMS_OUTPUT.PUT_LINE('Child''s Name: '||v_child_name);
DBMS_OUTPUT.PUT_LINE('Date of Birth: '||v_date_of_birth);
END;
DBMS_OUTPUT.PUT_LINE('Date of Birth: '||v_date_of_birth);
END;
END outer;
Dr Michel Nabaa PL/SQL 20
%TYPE attribute
• The %TYPE attribute lets you declare a variable, field, or
parameter to be of the same data type of a previously declared
variable or database column.
• If the referenced item changes, your declaration is automatically
updated.
• When the %TYPE attribute is used, it has to be prefixed by the
name of the database table and column name or the previously
declared variable it references.

Examples
v_emp_lname employees.last_name%TYPE;
v_balance NUMBER(7,2);
v_min_balance v_balance%TYPE := 1000;

Dr Michel Nabaa PL/SQL 21


PL/SQL Operators

• Arithmetic operators +, -. *, /, **
• Relational operators =, != or <> or ~=, >, <, >=, <=
• Comparison operators LIKE, BETWEEN, IN, IS NULL
• Logical operators AND, OR, NOT
• String functions and operators :

Dr Michel Nabaa PL/SQL 22


PL/SQL String functions and operators(1)
ASCII(x); Returns the ASCII value of the character x.

CHR(x); Returns the character with the ASCII value of x.

CONCAT(x, y); or || Concatenates the strings x and y and returns the appended
string.
INITCAP(x); Converts initial letter of words in x to uppercase and
returns that string.
INSTR(x, find_string [, start] [, occurrence]); Searches for find_string in x and returns the position at
which the specified occurrence occurs.
INSTRB(x, find_string [, start] [, occurrence]); Returns the location of the first byte of a specified
occurrence of a string within another string.
LENGTH(x); Returns the number of characters in x.

LENGTHB(x) Returns the length of a character string in bytes.

LOWER(x); Converts the letters in x to lowercase and returns that


string.
LPAD(x, width [, pad_string]) ; Pads x with spaces to the left, to bring the total length of
the string up to width characters.
LTRIM(x [, trim_string]); Trims characters from the left of x.

NANVL(x, value); Returns value if x matches the NaN special value (not a
number), otherwise x is returned.
Dr Michel Nabaa PL/SQL 23
PL/SQL String functions and operators(2)
NLS_LOWER(x) ; Same as the LOWER function except that it can use a different
sort method as specified by NLSSORT.
NLS_UPPER(x); Same as the UPPER function except that it can use a different
sort method as specified by NLSSORT.
NLSSORT(x); Changes the method of sorting the characters. Must be specified
before any NLS function; otherwise, the default sort will be
used.
NVL(x, value); Returns value if x is null; otherwise, x is returned.
NVL2(x, value1, value2); Returns value1 if x is not null; if x is null, value2 is returned.
REPLACE(x, search_string, replace_string); Searches x for search_string and replaces it with replace_string.

RPAD(x, width [, pad_string]); Pads x to the right.


RTRIM(x [, trim_string]); Trims x from the right.
SOUNDEX(x) ; Returns a string containing the phonetic representation of x.
SUBSTR(x, start [, length]); Returns a substring of x that begins at the position specified by
start. An optional length for the substring may be supplied.
SUBSTRB(x); Same as SUBSTR except that the parameters are expressed in
bytes instead of characters for the single-byte character systems.
TRIM([trim_character FROM ] x); Trims characters from the left and right of x.
UPPER(x); Converts the letters in x to uppercase and returns that string.
Dr Michel Nabaa PL/SQL 24
Programming Guidelines
Make code maintenance easier by:
• Documenting code with comments
• Developing a case convention for the code
• Developing naming conventions for identifiers and other
objects
• Enhancing readability by indenting

Dr Michel Nabaa PL/SQL 25


Code conventions
Category Case Convention Examples
SQL statements Uppercase SELECT, INSERT
PL/SQL keywords Uppercase DECLARE, BEGIN, IF
Data types Uppercase VARCHAR2,
BOOLEAN
Identifiers and Lowercase v_sal, emp_cursor, g_sal,
parameters p_empno
Database tables Lowercase, plural employees, departments

Database columns Lowercase, singular employee_id,


department_id

Dr Michel Nabaa PL/SQL 26


Naming Conventions
PL/SQL Structure Convention Examples
Variable v_variable_name v_sal
Constant c_constant_name c_rate
Subprogram parameter p_parameter_name p_id
Bind (host) variable b_bind_name b_sal
Cursor cur_cursor_name cur_emp
Record rec_record_name rec_emp
Type type_name_type books_type
Exception e_exception_name e_product_invalid

Dr Michel Nabaa PL/SQL 27


SELECT Statement in PL/SQL
SELECT select_list
INTO {variable_name[, variable_name]... |
record_name}
FROM table
[WHERE condition];
• SELECT INTO statement of SQL is used to retrieve a row
from the database and assign values to PL/SQL variables.
• For each item in the SELECT list, there must be a
corresponding, type-compatible variable in the INTO list.
• SELECT INTO statement returns only one row, so in most
cases, the WHERE clause is required.
• To retrieve multiple rows, we make use of explicit cursors

Dr Michel Nabaa PL/SQL 28


SELECT Statement in PL/SQL
DECLARE
v_id employees.employee_id%type := 100;
v_first_name employees.first_name%type;
v_last_name employees.last_name%TYPE;
v_salary employees.salary%type;

BEGIN
SELECT first_name, last_name, salary INTO v_first_name, v_last_name, v_salary
FROM Employees
WHERE employee_id = v_id;
DBMS_OUTPUT.PUT_LINE ('Employee ' ||v_first_name || v_last_name || ' earns ' ||
v_salary);
END;

Dr Michel Nabaa PL/SQL 29


Introduction to Cursors
• A cursor is a temporary work area created in the
system memory when a SQL statement is executed.
• Used to store the data retrieved from the database,
and to manipulate this data.
• A cursor can hold more than one row, but can process
only one row at a time.
• It can be named so that it could be referred to in a
program to fetch and process the rows returned by the
SQL statement.
• Two types of cursors:
– Implicit cursors
– Explicit cursors
Dr Michel Nabaa PL/SQL 30
Implicit Cursors (1)
• Are automatically created by Oracle whenever a
DML statements like, INSERT, UPDATE, and
DELETE statements are executed.
• They are also created when a SELECT statement that
returns just one row is executed.
• For INSERT operations, the cursor holds the data
that needs to be inserted. For UPDATE and
DELETE operations, the cursor identifies the rows
that would be affected.
• you can refer to the most recent implicit cursor as the
SQL cursor
• Each cursor has a set of attributes that can be
accessed by sql%attribute_name
Dr Michel Nabaa PL/SQL 31
Implicit Cursors (2)
SQL Cursor Attributes
Returns TRUE if an INSERT, UPDATE, or DELETE
statement affected one or more rows or a SELECT INTO
%FOUND
statement returned one or more rows. Otherwise, it
returns FALSE.
The logical opposite of %FOUND. It returns TRUE if an
INSERT, UPDATE, or DELETE statement affected no
%NOTFOUND
rows, or a SELECT INTO statement returned no rows.
Otherwise, it returns FALSE.
Always returns FALSE for implicit cursors, because
%ISOPEN Oracle closes the SQL cursor automatically after
executing its associated SQL statement.

Returns the number of rows affected by an INSERT,


%ROWCOUNT UPDATE, or DELETE statement, or returned by a
SELECT INTO statement.
Dr Michel Nabaa PL/SQL 32
Implicit Cursors (3)
Result
DECLARE
v_total_rows number(2);
37 employees
BEGIN
selected
UPDATE employees
SET salary = salary + 500
where salary < 4000;
IF SQL%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('no employees selected');
ELSIF SQL%FOUND THEN
v_total_rows := SQL%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE( v_total_rows || ' employees
selected ');
END IF;
END;
/

Dr Michel Nabaa PL/SQL 33


Explicit Cursors (1)
• Explicit cursors are declared and managed by the programmer
• They must be created when you are executing a SELECT statement
that returns more than one row. Even though the cursor stores
multiple records, only one record can be processed at a time, which
is called as current row.
• An explicit cursor should be defined in the declaration section of
the PL/SQL Block.
• The syntax for creating an explicit cursor is :
CURSOR cursor_name IS select_statement;

• Working with an explicit cursor includes the following steps :


1. Declaring the cursor.
2. Opening the cursor for allocating the memory.
3. Fetching the cursor one row at a time.
4. Closing the cursor to release the allocated memory.
Dr Michel Nabaa PL/SQL 34
Explicit Cursors (2)
Declaring the Cursor
• Defines the cursor with a name and the associated SELECT
statement.
CURSOR cur_employee IS SELECT employee_id, first_name,
last_name FROM employees;
Opening the Cursor
• Allocates the memory for the cursor, executes the query, identifies
the result set and makes the cursor ready for fetching the rows
returned by the SQL statement into it.
OPEN cur_employee;
Fetching the Cursor
• Involves accessing one row at a time
FETCH cur_employee INTO v_id, v_fname, v_lname;
Closing the Cursor
• Means releasing the allocated memory
CLOSE cur_employee;
Dr Michel Nabaa PL/SQL 35
Explicit Cursors (3)

DECLARE

CURSOR cursor_name IS Select Statement ;


BEGIN
OPEN cursor_name;
FETCH cursor_name INTO PL/SQL variables;
CLOSE cursor_name;
END;

Dr Michel Nabaa PL/SQL 36


Explicit Cursors (4)
DECLARE
v_id employees.employee_id%type;
v_fname employees.first_name%TYPE ;
v_lname employees.last_name%TYPE ;
CURSOR cur_employee is
SELECT employee_id, first_name, last_name FROM employees;
BEGIN
OPEN cur_employee;
LOOP
FETCH cur_employee into v_id, v_fname, v_lname;
EXIT WHEN cur_employee%notfound;
DBMS_OUTPUT.PUT_LINE(v_id || ' ' || v_fname || ' ' || v_lname);
END LOOP;
CLOSE cur_employee;
END;
/

Dr Michel Nabaa PL/SQL 37


Explicit Cursors with parameters
DECLARE
CURSOR cur_emp_fname (p_emp_id NUMBER) IS
SELECT first_name
FROM employees
WHERE employee_id < p_emp_id;
v_fname employees.first_name%TYPE;
BEGIN
OPEN cur_emp_fname (105);
LOOP
FETCH cur_emp_fname into v_fname;
EXIT WHEN cur_emp_fname%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (v_fname);
END LOOP;
CLOSE cur_emp_fname
END;
Many parameters can be specified separated by commas. Default values can be
assigned to parameters. In such a case, if you don’t supply arguments in the OPEN
CURSOR statement, default values are considered.
Dr Michel Nabaa PL/SQL 38
Cursor FOR LOOP
• It is a type of FOR LOOP which makes working with
cursors a lot easier.
• CURSOR FOR LOOP will do automatically the steps
of opening, fetching and closing the cursor.

• Synthax
FOR loop_index IN cursor_name
LOOP
Statements …………
END LOOP;

Dr Michel Nabaa PL/SQL 39


Cursor FOR LOOP
DECLARE
CURSOR cur_emp_fname IS
SELECT first_name
FROM employees
WHERE employee_id < 105;
BEGIN
FOR emp_rec IN cur_emp_fname
LOOP
DBMS_OUTPUT.PUT_LINE (emp_rec.first_name);
END LOOP;
END;

Cursor For Loop can also be parameterized


CURSOR cur_emp_fname ( (p_emp_id NUMBER) IS …
WHERE employee_id < p_emp_id; ….
BEGIN
FOR emp_rec IN cur_emp_fname (105) …………..

Dr Michel Nabaa PL/SQL 40


PL/SQL Control Statements

Three categories of control statements:

• Conditional Selection Statements IF, CASE


• LOOP Statements LOOP, FOR LOOP, and
WHILE LOOP.
• Sequential Control Statements GOTO, NULL

Dr Michel Nabaa PL/SQL 41


Conditional Selection Statements(1)
The conditional selection statements, IF and CASE, run
different statements for different data values.
The IF statement either runs or skips a sequence of one
or more statements, depending on a condition.

The IF statement has these forms:

IF THEN
IF THEN ELSE
IF THEN ELSIF

Dr Michel Nabaa PL/SQL 42


Conditional Selection Statements(2)
IF condition THEN If the condition is true, the statements run;
statements otherwise, the IF statement does nothing
END IF;
IF condition THEN If the value of condition is true, the statements
statements run; otherwise, the else_statements run
ELSE
else_statements
END IF;
IF condition_1 THEN The IF THEN ELSIF statement runs the first
statements_1 statements for which condition is true.
ELSIF condition_2 THEN Remaining conditions are not evaluated. If no
statements_2 condition is true, the else_statements run, if
[ ELSIF condition_3 THEN they exist; otherwise, the IF THEN ELSIF
statements_3 statement does nothing.
]...
[ ELSE A single IF THEN ELSIF statement is easier to
else_statements understand than a logically equivalent nested
] IF THEN ELSE statement:
END IF;
Dr Michel Nabaa PL/SQL 43
Conditional Selection Statements(3)
IF then ELSE
DECLARE
PROCEDURE p (p_sales NUMBER) IS
v_bonus NUMBER := 0;
BEGIN
IF p_sales > 50000 THEN v_bonus := 1500;
ELSIF p_sales > 35000 THEN v_bonus := 500;
ELSE v_bonus := 100;
END IF;
DBMS_OUTPUT.PUT_LINE ( 'Sales = ' || sales || ', bonus = ' || v_bonus || '.' );
END p;

BEGIN
p(55000);
p(40000);
p(30000);
END;

Dr Michel Nabaa PL/SQL 44


Conditional Selection Statements(4)
Simple CASE Statement
CASE selector The selector is an expression (typically
WHEN selector_value_1 THEN statements_1 a single variable). Each selector_value
WHEN selector_value_2 THEN statements_2 can be either a literal or an expression.
... The simple CASE statement runs the
WHEN selector_value_n THEN statements_n first statements for which
[ ELSE selector_value equals selector.
else_statements ] Remaining conditions are not
END CASE;] evaluated. If no selector_value equals
selector, the CASE statement runs
else_statements if they exist and raises
the predefined exception
CASE_NOT_FOUND otherwise.

Simple CASE Statement can be simulated by ELSIF Statement


Dr Michel Nabaa PL/SQL 45
Conditional Selection Statements(5)
Searched CASE Statement
CASE The searched CASE statement runs the
WHEN condition_1 THEN statements_1 first statements for which condition is
WHEN condition_2 THEN statements_2 true. Remaining conditions are not
... evaluated. If no condition is true, the
WHEN condition_n THEN statements_n CASE statement runs else_statements
[ ELSE if they exist and raises the predefined
else_statements ] exception CASE_NOT_FOUND
END CASE;] otherwise.

Dr Michel Nabaa PL/SQL 46


Conditional Selection Statements(6)
Simple Case Statement
DECLARE
v_grade CHAR(1);
BEGIN
v_grade := 'B';
CASE v_grade
WHEN 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent');
WHEN 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good');
WHEN 'C' THEN DBMS_OUTPUT.PUT_LINE('Good');
WHEN 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair');
WHEN 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor');
ELSE DBMS_OUTPUT.PUT_LINE('No such grade');
END CASE;
END;
/
Output
Very Good
Dr Michel Nabaa PL/SQL 47
Conditional Selection Statements(6)
Searched Case Statement
DECLARE
v_grade CHAR(1);
BEGIN
v_grade := 'B';
CASE
WHEN v_grade = 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent');
WHEN v_grade = 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good');
WHEN v_grade = 'C' THEN DBMS_OUTPUT.PUT_LINE('Good');
WHEN v_grade = 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair');
WHEN v_grade = 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor');
ELSE DBMS_OUTPUT.PUT_LINE('No such grade');
END CASE;
END;
/

Result
Very Good
Dr Michel Nabaa PL/SQL 48
LOOP Statements
A loop statement allows us to execute a statement or
group of statements multiple times.
• Basic LOOP
• WHILE LOOP
• FOR LOOP
• Nested Loops

LOOP statements can be labeled.


Labels are recommended for nested loops to improve readability.
The label in an END LOOP statement should match the label at the
beginning of the same loop statement.

Dr Michel Nabaa PL/SQL 49


The Loop Control Statements
Loop control statements change execution from its normal
sequence.

EXIT statement Completes the loop and control passes to the


statement immediately after the END LOOP.

CONTINUE statement Causes the loop to skip the remainder of its


body and immediately retest its condition prior to reiterating.

GOTO statement Transfers control to the labeled statement.


Though it is not advised to use the GOTO statement in your program.

Dr Michel Nabaa PL/SQL 50


Basic LOOP with EXIT Statement
[ label ]
LOOP
statements
END LOOP [ label ];

• The label should be enclosed by double angle brackets (<< and >>)
and appear at the beginning of the LOOP statement, it can also
appear at the end of the LOOP statement and in the EXIT statement.
• An EXIT statement or an EXIT WHEN statement is required to
break the loop.

Dr Michel Nabaa PL/SQL 51


Basic LOOP with EXIT Statement
DECLARE Result
v_count number := 10;
BEGIN 10
LOOP 20
DBMS_OUTPUT.PUT_LINE(v_count); 30
v_count := v_count + 10; 40
IF v_count > 50 THEN 50
EXIT; After Exit v_count is: 60
END IF;
END LOOP; PL/SQL procedure
-- after exit, control resumes here successfully completed.
DBMS_OUTPUT.PUT_LINE('After Exit v_count is: '
|| v_count);
END;
/

Dr Michel Nabaa PL/SQL 52


Basic LOOP with EXIT WHEN
Statement
Result
DECLARE
v_count number := 10; 10
BEGIN 20
LOOP 30
DBMS_OUTPUT.PUT_LINE(v_count); 40
v_count := v_count + 10; 50
EXIT WHEN v_count > 50; After Exit v_count is: 60
END LOOP;
-- after exit, control resumes here PL/SQL procedure
DBMS_OUTPUT.PUT_LINE ('After Exit v_count is: successfully completed.
' || v_count);
END;
/

Dr Michel Nabaa PL/SQL 53


WHILE LOOP Statement
WHILE condition LOOP
sequence_of_statements
END LOOP;
Result
DECLARE value of v_n: 10
v_n number(2) := 10; value of v_n: 11
BEGIN value of v_n: 12
WHILE v_n < 20 LOOP value of v_n: 13
DBMS_OUTPUT.PUT_LINE('value of v_n: ' || value of v_n: 14
v_n); value of v_n: 15
v_n := v_n + 1; value of v_n: 16
END LOOP; value of v_n: 17
END; value of v_n: 18
/ value of v_n: 19

PL/SQL procedure
successfully completed.
Dr Michel Nabaa PL/SQL 54
FOR LOOP Statement
FOR counter IN initial_value .. final_value LOOP
sequence_of_statements;
END LOOP;
Result
DECLARE value of v_n: 10
v_n number(2); value of v_n: 11
BEGIN value of v_n: 12
FOR v_n in 10 .. 20 LOOP value of v_n: 13
DBMS_OUTPUT.PUT_LINE('value of v_n: ' || value of v_n: 14
v_n); value of v_n: 15
END LOOP; value of v_n: 16
END; value of v_n: 17
/ value of v_n: 18
value of v_n: 19
value of v_n: 20

PL/SQL procedure
successfully completed.
Dr Michel Nabaa PL/SQL 55
Reverse FOR LOOP Statement
FOR counter IN REVERSE initial_value .. final_value
LOOP
sequence_of_statements;
END LOOP;
Result
DECLARE value of v_n: 20
v_n number(2) ; value of v_n: 19
value of v_n: 18
BEGIN
value of v_n: 17
FOR v_n IN REVERSE 10 .. 20 LOOP value of v_n: 16
DBMS_OUTPUT.PUT_LINE('value of v_n: ' || value of v_n: 15
v_n); value of v_n: 14
END LOOP; value of v_n: 13
END; value of v_n: 12
/ value of v_n: 11
value of v_n: 10

PL/SQL procedure successfully


completed.
Dr Michel Nabaa PL/SQL 56
CONTINUE Statement
It forces the next iteration of the loop to take place,
skipping any code in between.
Result
DECLARE value of v_n: 10
v_n number(2) := 10; value of v_n: 11
BEGIN value of v_n: 12
-- while loop execution value of v_n: 13
WHILE v_n < 20 LOOP value of v_n: 14
DBMS_OUTPUT.PUT_LINE ('value of v_n: ' || v_n); value of v_n: 16
IF v_n = 15 THEN value of v_n: 17
-- skip the loop using the CONTINUE statement value of v_n: 18
CONTINUE; value of v_n: 19
END IF;
v_n := v_n + 1; PL/SQL procedure successfully
END LOOP; completed.
END;
/

Dr Michel Nabaa PL/SQL 57


GOTO Statement
Result
GOTO label; value of v_n: 10
DECLARE
.. v_n number(2) := 10; value of v_n: 11
BEGIN value of v_n: 12
<< label >> value of v_n: 13
<<loopstart>>
statement; -- while loop execution value of v_n: 14
WHILE v_n < 20 LOOP value of v_n: 16
DBMS_OUTPUT.PUT_LINE ('value of v_n: ' || value of v_n: 17
v_n); value of v_n: 18
v_n := v_n + 1; value of v_n: 19
IF v_n = 15 THEN
v_n := v_n + 1; PL/SQL procedure
GOTO loopstart; successfully
END IF; completed.
END LOOP;
END;
/

Dr Michel Nabaa PL/SQL 58


GOTO Statement
• The use of GOTO statement makes it difficult to trace the control
flow of a program, making it hard to understand and hard to
modify.
• A GOTO statement cannot branch into an IF statement, CASE
statement, LOOP statement or sub-block.
• A GOTO statement cannot branch from an outer block into a sub-
block (i.e., an inner BEGIN-END block).
• A GOTO statement cannot branch out of a subprogram. To end a
subprogram early, either use the RETURN statement or have
GOTO branch to a place right before the end of the subprogram.
• A GOTO statement cannot branch from an exception handler back
into the current BEGIN-END block.

Dr Michel Nabaa PL/SQL 59


Composite Data Types
 Can hold multiple values (unlike scalar types)
 Are of two types:
– PL/SQL records
– PL/SQL collections
• Associative array (INDEX BY table)
• Nested table
• VARRAY

Dr Michel Nabaa PL/SQL 60


Composite Data Types
 PL/SQL records are used to store values of different data
types that are logically related. Ex Employee record to hold
employee details. Records Are similar to structures in most
third-generation languages (including C and C++).

 PL/SQL collections are used to store values of the same


data type that can also be a composite type (such as records).
Ex a collection to hold the first names of all employees.
These collections are similar to arrays in programming
languages such as C, C++, and Java.

Dr Michel Nabaa PL/SQL 61


Records

PL/SQL can handle the following types of records :


• Table-based
• Cursor-based records
• User-defined records

Dr Michel Nabaa PL/SQL 62


Table-Based Records
The %ROWTYPE attribute enables a programmer to create
table-based and cursor based records.
DECLARE
rec_emp employees%rowtype;
BEGIN
SELECT * into rec_emp
FROM employees
WHERE employee_id = 107;
DBMS_OUTPUT.PUT_LINE('Employee id: ' || rec_emp.employee_id);
DBMS_OUTPUT.PUT_LINE('Employee Firstname: ' ||
rec_emp.first_name);
DBMS_OUTPUT.PUT_LINE('Employee Lastname: ' ||
rec_emp.last_name);
DBMS_OUTPUT.PUT_LINE('Employee Salary: ' || rec_emp.salary);
END;
/
Dr Michel Nabaa PL/SQL 63
Cursor-Based Records
DECLARE
CURSOR cur_employee is
SELECT employee_id, first_name, last_name, salary
FROM employees;
rec_employee cur_employee%rowtype;
BEGIN
OPEN cur_employee;
LOOP
FETCH cur_employee into rec_employee;
EXIT WHEN cur_employee%notfound;
DBMS_OUTPUT.PUT_LINE(rec_employee.employee_id || ' ' ||
rec_employee.first_name || ' ' ||
rec_employee.last_name || ' ' ||
rec_employee.salary );
END LOOP;
END;
/
Dr Michel Nabaa PL/SQL 64
User-Defined Records (1)

PL/SQL allows you to define types of records and declare record


variables of these types.

TYPE type_name IS RECORD


( field_name1 datatype1 [NOT NULL] [:= DEFAULT EXPRESSION],
field_name2 datatype2 [NOT NULL] [:= DEFAULT EXPRESSION],
...
field_nameN datatypeN [NOT NULL] [:= DEFAULT EXPRESSION);

record-name type_name;

Dr Michel Nabaa PL/SQL 65


User-Defined Records (2)
• To access any field of a record, we use the dot (.) operator.
• A record can be passed as a subprogram parameter just as any other variable.
DECLARE
TYPE t_rec_type IS RECORD
(v_sal number(8),
v_minsal number(8) default 1000,
v_hire_date employees.hire_date%type,
v_rec1 employees%rowtype);
v_myrec t_rec_type;
BEGIN
v_myrec.v_sal := v_myrec.v_minsal + 500;
v_myrec.v_hire_date := sysdate;
SELECT * INTO v_myrec.v_rec1
FROM employees
WHERE employee_id = 100;
DBMS_OUTPUT.PUT_LINE(v_myrec.v_rec1.last_name ||' '||
to_char(v_myrec.v_hire_date) ||' '|| to_char(v_myrec.v_sal));
END;
Dr Michel Nabaa PL/SQL 66
PL/SQL Program Units
A PL/SQL unit is any one of the following :
– Subprogram
– Function
– Procedure
– Trigger
– Package
– Package body
– Type
– Type body

Dr Michel Nabaa PL/SQL 67


Subprograms (1)
• A subprogram is a program unit/module that performs a particular
task.
• Subprograms are combined to form larger programs ➔ 'Modular
design'.
• A subprogram can be invoked by another subprogram or program
which is called the calling program.
• A subprogram can be created
– At the schema level ➔ Standalone subprogram
– Inside a package ➔ packaged subprogram
– Inside a PL/SQL block ➔ Nested subprogram

Dr Michel Nabaa PL/SQL 68


Subprograms (2)
• Standalone subprogram is created with the CREATE
PROCEDURE or the CREATE FUNCTION statement. It is stored
in the database and can be deleted with the DROP PROCEDURE
or DROP FUNCTION statement.

• Packaged subprogram is stored in the database and can be


deleted only when the package is deleted with the DROP
PACKAGE statement.

Dr Michel Nabaa PL/SQL 69


Subprograms (3)
Reasons to use subprograms
• Modularity, Subprograms let you break a program into
manageable, well-defined modules.
• Easier Application Design, the implementation details of the
subprograms can be deferred until the main program is tested, then
the subprograms are refined one step at a time.
• Maintainability, the implementation details of a subprogram can
be changed without changing its invokers.
• Packageability, Subprograms can be grouped into packages
• Reusability, Any number of applications, in many different
environments, can use the same package subprogram or standalone
subprogram.
• Better Performance, Stored subprograms are cached and shared
among users, which lowers memory requirements and invocation
overhead.
Dr Michel Nabaa PL/SQL 70
Subprograms (4)
• A PL/SQL subprogram is a named PL/SQL bloc that can be
invoked with a set of parameters.
• Two kinds of subprograms :
– Procedures mainly used to perform each one or more
specific task. A procedure may or may not return any value.
– Functions return a single value. A function is mainly used
to compute and return a value.

• Like anonymous PL/SQL blocks, the named blocks will also have
the following three parts :
– Declarative part
– Executable part
– Error handling or Exception part

Dr Michel Nabaa PL/SQL 71


Procedures (1)
• A Standalone procedure is created or modified with the CREATE
OR REPLACE PROCEDURE statement.

CREATE [OR REPLACE] PROCEDURE procedure_name


[(parameter_name [IN | OUT | IN OUT] type [, ...])]
{IS | AS}
BEGIN
< procedure_body >
END procedure_name;

CREATE OR REPLACE PROCEDURE greetings


AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Hello World!');
END;
/
Dr Michel Nabaa PL/SQL 72
Procedures (2)
• The optional parameters declared in the subprogram heading are
called formal parameters.
• In each formal parameter declaration, specify the name and data type
of the parameter, and (optionally) its mode and default value.
• IN represents the value that will be passed from outside
• OUT represents the parameter that will be used to return a value
outside of the procedure.
• procedure-body contains the executable part.
• The AS keyword is used instead of the IS keyword for creating a
standalone procedure.
• When invoking the subprogram, actual parameters are specified
and their values are assigned to the corresponding formal
parameters.
• Corresponding actual and formal parameters must have compatible
data types.
Dr Michel Nabaa PL/SQL 73
Procedures (3)
• A standalone procedure can be called in two ways:
– Using the EXECUTE keyword EXECUTE greetings;
– Calling the name of the procedure from a PL/SQL block

BEGIN
greetings;
END;
/
• A standalone procedure is deleted with the DROP PROCEDURE
statement.

DROP PROCEDURE greetings;

Dr Michel Nabaa PL/SQL 74


Parameter Modes in PL/SQL
Subprograms (1)
Three modes : IN, OUT and IN/OUT
• IN :
– Lets you pass a value to the subprogram.
– It is a read-only parameter that acts like a constant.
– You can also initialize it to a default value; however, in that
case, it is omitted from the subprogram call.
– It is the default mode of parameter passing.
– Parameters are passed by reference.
• OUT :
– Returns a value to the calling program.
– Inside the subprogram, an OUT parameter acts like a variable.
– The actual parameter must be variable and it is passed by
value.
Dr Michel Nabaa PL/SQL 75
Parameter Modes in PL/SQL
Subprograms (2)
• IN / OUT :
– Passes an initial value to a subprogram and returns an updated
value to the caller.
– It can be assigned a value and the value can be read.
– The actual parameter corresponding to an IN OUT formal
parameter must be a variable, not a constant or an expression.
– Formal parameter must be assigned a value.
– Actual parameter is passed by value.

Dr Michel Nabaa PL/SQL 76


Parameter Modes in PL/SQL
Subprograms (3)
CREATE OR REPLACE PROCEDURE findMin(p_x IN number, p_y IN number, p_z
OUT number)
IS
BEGIN
IF p_x < p_y THEN p_z:= p_x;
ELSE p_z:= p_y;
END IF;
END;
From a separated SQL file, we add the following code to execute the procedure.
DECLARE
v1 number; v2 number; v3 number;
BEGIN
v1:= 23; v2:= 45;
findMin(v1, v2, v3);
DBMS_OUTPUT.PUT_LINE(' Minimum of (23, 45) : ' || v3);
END;

Result
Minimum of (23, 45) : 23
PL/SQL procedure successfully completed.
Dr Michel Nabaa PL/SQL 77
Parameter Modes in PL/SQL
Subprograms (4)
CREATE OR REPLACE PROCEDURE squareNum(p_x IN OUT number) IS
BEGIN
p_x := p_x * p_x;
END;

From a separated SQL file, we add the following code to execute the procedure.

DECLARE
v1 number;
BEGIN
v1:= 23;
squareNum(v1);
DBMS_OUTPUT.PUT_LINE(' Square of (23): ' || v1);
END;

Result
Square of (23): 529

PL/SQL procedure successfully completed.


Dr Michel Nabaa PL/SQL 78
Functions (1)
A function is same as a procedure except that it returns a
value. A standalone function is created or modified with the
following instruction:

CREATE [OR REPLACE] FUNCTION function_name


[(parameter_name [IN | OUT | IN OUT] type [, ...])]
RETURN return_datatype
{IS | AS}
BEGIN
< function_body >
END [function_name];

RETURN clause specifies the data type of the value returned from the function.
AS keyword is used instead of the IS keyword for creating a standalone function.

Dr Michel Nabaa PL/SQL 79


Functions (2)
CREATE OR REPLACE FUNCTION totalemployees
RETURN number AS
v_total number(3) := 0;
BEGIN
SELECT count(*) into v_total
FROM employees;
RETURN v_total;
END;

From a separated SQL file, we add the following code to execute the
procedure.

Declare
v_nbemp number(3) := 0;
BEGIN
v_nbemp := totalemployees();
DBMS_OUTPUT.PUT_LINE('Total no. of employees: ' || v_nbemp);
END;
Dr Michel Nabaa PL/SQL 80
Notations used for Passing Parameters
(1)
Actual parameters can be passed in three ways :
• Positional Notation :
– In positional notation, the first actual parameter is substituted
for the first formal parameter; the second actual parameter is
substituted for the second formal parameter, and so on.
findMin( v1, v2, v3 );
• Named Notation :
– the actual parameter is associated with the formal parameter
using the arrow symbol ( => ).
findMin(p_x => v1, p_y => v2, p_z => v3);
• Mixed Notation
– you can mix both notations in procedure call; however, the
positional notation should precede the named notation
findMin(v1, v2, p_z => v3);
Dr Michel Nabaa PL/SQL 81
Notations used for Passing Parameters
DECLARE (2)
v_emp_num NUMBER(6) := 100;
Result
v_bonus NUMBER(6) := 50;
v_salary employees.salary%type; Employee salary : 24400
PROCEDURE raise_salary ( p_emp_id NUMBER, p_amount NUMBER ) Employee salary : 24450
IS
BEGIN Employee salary : 24500
UPDATE employees Employee salary : 24550
SET salary = salary + p_amount Employee salary : 24600
WHERE employee_id = p_emp_id;
END raise_salary;
BEGIN
----- Equivalent invocations:
SELECT salary INTO v_salary FROM employees WHERE employee_id = v_emp_num;
DBMS_OUTPUT.PUT_LINE('employee salary:'|| v_salary);
raise_salary(v_emp_num, v_bonus);
SELECT salary INTO v_salary FROM employees WHERE employee_id = v_emp_num;
DBMS_OUTPUT.PUT_LINE('employee salary:'|| v_salary); -- positional notation
raise_salary(p_amount => v_bonus, p_emp_id => v_emp_num);
SELECT salary INTO v_salary FROM employees WHERE employee_id = v_emp_num;
dbms_output.put_line('employee salary:'|| v_salary); -- named notation
raise_salary(p_emp_id => v_emp_num, p_amount => v_bonus);
SELECT salary INTO v_salary FROM employees WHERE employee_id = v_emp_num;
DBMS_OUTPUT.PUT_LINE('employee salary:'|| v_salary); -- named notation
raise_salary(v_emp_num, p_amount => v_bonus);
SELECT salary INTO v_salary FROM employees WHERE employee_id = v_emp_num;
DBMS_OUTPUT.PUT_LINE('employee salary:'|| v_salary); -- mixed notation
END;
/

Dr Michel Nabaa PL/SQL 82


Exceptions (1)
• An error occurring during a program execution triggers what we call an
exception is an exception.
• Using EXCEPTION block in the program, an appropriate action is taken
against the error condition.
• Two types of exceptions :
– System-defined exceptions
– User-defined exceptions DECLARE
<declarations section>
BEGIN
<executable command(s)>
EXCEPTION
<exception handling goes here >
WHEN exception1 THEN
exception1-handling-statements
WHEN exception2 THEN
exception2-handling-statements
........
WHEN others THEN
other-errors-handling-statements
END;
Dr Michel Nabaa PL/SQL 83
Exceptions (2)
DECLARE
v_id employees.employee_id%type := 10;
v_fname employees.first_name%type;
v_lname employees.last_name%type;
BEGIN
SELECT first_name, last_name INTO v_fname, v_lname
FROM employees
WHERE employee_id = v_id;
DBMS_OUTPUT.PUT_LINE ('first name: '|| v_fname);
DBMS_OUTPUT.PUT_LINE ('last name: ' || v_lname);
EXCEPTION
WHEN no_data_found THEN
DBMS_OUTPUT.PUT_LINE('No such employees!');
WHEN others THEN
DBMS_OUTPUT.PUT_LINE('Error!');
END;
/

Dr Michel Nabaa PL/SQL 84


User-defined Exceptions (1)

• PL/SQL allows you to define your own exceptions


according to the need of your program.

• A user-defined exception must be declared and then


raised explicitly using either the PL/SQL RAISE
statement or the procedure
DBMS_STANDARD.RAISE_APPLICATION_ERROR.

Dr Michel Nabaa PL/SQL 85


User-defined Exceptions (2)
DECLARE EXCEPTION
v_id employees.employee_id%type := &ee_id; WHEN e_invalid_id THEN
v_fname employees.first_name%type; DBMS_OUTPUT.PUT_LINE('ID must
v_lname employees.last_name%type; be greater than zero!');
-- user defined exception WHEN no_data_found THEN
e_invalid_id EXCEPTION; DBMS_OUTPUT.PUT_LINE('No such
BEGIN customer!');
IF v_id <= 0 THEN WHEN others THEN
RAISE e_invalid_id; DBMS_OUTPUT.PUT_LINE('Error!');
ELSE END;
SELECT first_name, last_name INTO v_fname, v_lname
FROM employees
WHERE employee_id = v_id;
DBMS_OUTPUT.PUT_LINE ('first name: '|| v_fname);
DBMS_OUTPUT.PUT_LINE ('last name: ' || v_lname);
END IF;

Dr Michel Nabaa PL/SQL 86


Pre-defined Exceptions (1)
Exception Oracle Error SQLCODE Description

ACCESS_INTO_NULL 06530 -6530 It is raised when a null object is automatically assigned a value.

It is raised when none of the choices in the WHEN clause of a


CASE_NOT_FOUND 06592 -6592 CASE statement is selected, and there is no ELSE clause.

It is raised when a program attempts to apply collection methods


other than EXISTS to an uninitialized nested table or varray, or
COLLECTION_IS_NULL 06531 -6531 the program attempts to assign values to the elements of an
uninitialized nested table or varray.

It is raised when duplicate values are attempted to be stored in a


DUP_VAL_ON_INDEX 00001 -1 column with unique index.

It is raised when attempts are made to make a cursor operation


INVALID_CURSOR 01001 -1001 that is not allowed, such as closing an unopened cursor.

It is raised when the conversion of a character string into a


INVALID_NUMBER 01722 -1722 number fails because the string does not represent a valid
number.

ACCESS_INTO_NULL 06530 -6530 It is raised when a null object is automatically assigned a value.

It is raised when none of the choices in the WHEN clause of a


CASE_NOT_FOUND 06592 -6592 CASE statement is selected, and there is no ELSE clause.
Dr Michel Nabaa PL/SQL 87
Pre-defined Exceptions (2)
Exception Oracle Error SQLCODE Description

It is raised when a database call is issued without being


NOT_LOGGED_ON 01012 -1012 connected to the database.

PROGRAM_ERROR 06501 -6501 It is raised when PL/SQL has an internal problem.

It is raised when a cursor fetches value in a variable having


ROWTYPE_MISMATCH 06504 -6504 incompatible data type.

It is raised when a member method is invoked, but the instance


SELF_IS_NULL 30625 -30625 of the object type was not initialized.

It is raised when PL/SQL ran out of memory or memory was


STORAGE_ERROR 06500 -6500 corrupted.

It is raised when a SELECT INTO statement returns more than


TOO_MANY_ROWS 01422 -1422 one row.

It is raised when an arithmetic, conversion, truncation, or


VALUE_ERROR 06502 -6502 sizeconstraint error occurs.

ZERO_DIVIDE 01476 1476 It is raised when an attempt is made to divide a number by zero.

Dr Michel Nabaa PL/SQL 88


Triggers (1)
• Triggers are stored programs, which are automatically
executed, fired when some events occur.
• Triggers are, in fact, written to be executed in response to
any of the following events :
– A DML statement (DELETE, INSERT, or UPDATE)
– A DDL statement (CREATE, ALTER, or DROP).
– A database operation (SERVERERROR, LOGON,
LOGOFF, STARTUP, or SHUTDOWN).

• Triggers can be defined on the table, view, schema, or


database with which the event is associated.
• A trigger cannot execute the COMMIT, ROLLBACK, or
SAVEPOINT commands.
Dr Michel Nabaa PL/SQL 89
Triggers (2)
• A trigger can be enabled and disabled, but you cannot
explicitly invoke it, the database automatically invokes it
whenever its triggering event occurs. While a trigger
is disabled, it does not fire.

• Triggers are of two types


– Row level trigger, is executed for each row updated,
inserted or deleted.
– Statement level trigger, is executed only once even
though the modifications concern many rows of the
table, so it executes only once per SQL statement.

Dr Michel Nabaa PL/SQL 90


Triggers (3)
CREATE [OR REPLACE ] TRIGGER trigger_name
{BEFORE | AFTER | INSTEAD OF }
{INSERT [OR] | UPDATE [OR] | DELETE}
[OF col_name]
ON table_name
[REFERENCING OLD AS o NEW AS n]
[FOR EACH ROW]
WHEN (condition)
DECLARE
Declaration-statements
BEGIN
Executable-statements
EXCEPTION
Exception-handling-statements
END;
Dr Michel Nabaa PL/SQL 91
Triggers (4)
CREATE OR REPLACE TRIGGER display_salary_changes
BEFORE DELETE OR INSERT OR UPDATE ON employees
FOR EACH ROW
WHEN (NEW.job_id <> 'AD_PRES')
DECLARE
v_sal_diff number;
BEGIN
v_sal_diff := :NEW.salary - :OLD.salary;
dbms_output.put_line('Old salary: ' || :OLD.salary);
dbms_output.put_line('New salary: ' || :NEW.salary);
dbms_output.put_line('Salary difference: ' || v_sal_diff);
dbms_output.put_line(chr(0)); -- to print blank line
END;
/

Dr Michel Nabaa PL/SQL 92


Triggers (5)
A trigger that logs changes to EMPLOYEES.SALARY
DROP TABLE Emp_log;
CREATE TABLE Emp_log (
emp_id NUMBER,
log_date DATE,
new_salary NUMBER,
action VARCHAR2(20));

CREATE OR REPLACE TRIGGER log_salary_increase


AFTER UPDATE OF salary ON employees
FOR EACH ROW
BEGIN
INSERT INTO emp_log (emp_id, log_date, new_salary, action)
VALUES (:NEW.employee_id, SYSDATE, :NEW.salary, 'New Salary');
END;
/
UPDATE employees
SET salary = salary + 1000.0
WHERE department_id = 100;

Dr Michel Nabaa PL/SQL 93


Triggers (6)
Disable a Trigger
ALTER TRIGGER trigger_name DISABLE;

Disable all Triggers on a table


ALTER TABLE table_name DISABLE ALL TRIGGERS;

Enable a Trigger
ALTER TRIGGER trigger_name ENABLE;

Enable all Triggers on a table


ALTER TABLE table_name DISABLE ALL TRIGGERS;

Drop a trigger
DROP TRIGGER trigger_name;
Dr Michel Nabaa PL/SQL 94
Benefits of Triggers
Triggers can be written for the following purposes :

– Generating some derived column values automatically


– Enforce referential integrity when child and parent tables are on
different nodes of a distributed database.
– Enforce complex business or referential integrity rules that you
cannot define with constraints.
– Event logging.
– Synchronous replication of tables.
– Prevent DML operations on a table after regular business hours.

Dr Michel Nabaa PL/SQL 95


How Triggers and Constraints Differ
• Both triggers and constraints can constrain data input, but they
differ significantly:
– A trigger always applies to new data only.
– A constraint can apply either to new data only (like a trigger) or
to both new and existing data.
– Constraints are easier to write and less error-prone than triggers
that enforce the same rules. However, triggers can enforce
some complex business rules that constraints cannot.
– Oracle strongly recommends that you use triggers to constrain
data input only in these situations:
o To enforce referential integrity when child and parent tables
are on different nodes of a distributed database
o To enforce complex business or referential integrity rules
that you cannot define with constraints
Dr Michel Nabaa PL/SQL 96
Packages

• Packages are schema objects that groups logically


related PL/SQL types, variables, subprograms,
cursors, and exceptions.
• A package is compiled and stored in the database,
where many applications can share its contents.
• A package has two mandatory parts :
– Package specification or declaration
– Package body or definition

Dr Michel Nabaa PL/SQL 97


Package Specification
• The interface to the package.
• It just DECLARES the types, variables, constants,
exceptions, cursors, and subprograms that can be
referenced from outside the package.
• All objects placed in the specification are called public
objects.
• Any subprogram not in the package specification but
coded in the package body is called a private object.
• The package specification has to be compiled
successfully first, then compile the package body.

Dr Michel Nabaa PL/SQL 98


Package Specification
CREATE PACKAGE first_package AS
PROCEDURE find_sal(e_id employees.employee_id%type);
FUNCTION totalemployees RETURN number;
END first_package;
/

Package created.

Dr Michel Nabaa PL/SQL 99


Package Body

• has the codes for various variables, procedures and


functions declared in the package specification and other
private declarations, which are hidden from the code
outside the package.

• Package body cannot exist without package specification.

• Package specification can be defined without a body.

Dr Michel Nabaa PL/SQL 100


Package Body
CREATE OR REPLACE PACKAGE BODY first_package AS
PROCEDURE find_sal(p_id employees.employee_id%type) IS
v_sal employees.salary%TYPE;
BEGIN
SELECT salary INTO v_sal
FROM employees
WHERE employee_id = p_id;
DBMS_OUTPUT.PUT_LINE('Salary: '|| v_sal);
END find_sal;

FUNCTION totalemployees RETURN number IS


v_total number(3) := 0;
BEGIN
SELECT count(*) into v_total
FROM employees;
RETURN v_total;
END;
END first_package;

Dr Michel Nabaa PL/SQL 101


Using the Package Elements
• The package elements (variables, procedures or functions) are
accessed with the following syntax :

package_name.element_name;

Dr Michel Nabaa PL/SQL 102

You might also like