0% found this document useful (0 votes)
103 views220 pages

PLSQL

PL/SQL is Oracle's standard language for accessing and manipulating data in Oracle databases. It seamlessly integrates SQL queries and procedural constructs like variables, conditions, and loops. PL/SQL provides a block structure that makes code maintenance easier. It offers benefits like improved performance, modular programming, and exception handling. Variables are declared and initialized in the declarative section and then used in the executable section. They can be scalar, composite, reference, or LOB types.

Uploaded by

suresh babu
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
103 views220 pages

PLSQL

PL/SQL is Oracle's standard language for accessing and manipulating data in Oracle databases. It seamlessly integrates SQL queries and procedural constructs like variables, conditions, and loops. PL/SQL provides a block structure that makes code maintenance easier. It offers benefits like improved performance, modular programming, and exception handling. Variables are declared and initialized in the declarative section and then used in the executable section. They can be scalar, composite, reference, or LOB types.

Uploaded by

suresh babu
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 220

Introduction to PL/SQL

About PL/SQL
• PL/SQL:
– Stands for “Procedural Language extension to SQL”
– Is Oracle Corporation’s standard data access language
for relational databases
– Seamlessly integrates procedural constructs with SQL
About PL/SQL
• PL/SQL:
– Provides a block structure for executable units of code.
Maintenance of code is made easier with such a well-
defined structure.
– Provides procedural constructs such as:
• Variables, constants, and data types
• Control structures such as conditional statements and loops
• Reusable program units that are written once and executed
many times
PL/SQL Environment

PL/SQL engine

procedural Procedural
PL/SQL statement
PLSQL
block executor
SQL

SQL statement
executor

Oracle database server


Benefits of PL/SQL
– Integration of procedural constructs with SQL
– Improved performance

SQL 1
SQL 2

SQL
IF...THEN
SQL
ELSE
SQL
END IF;
SQL
Benefits of PL/SQL
– Modularized program development
– Integration with Oracle tools
– Portability
– Exception handling
PL/SQL Block Structure
– DECLARE (optional)
• Variables, cursors, user-defined exceptions
– BEGIN (mandatory)
• SQL statements
• PL/SQL statements
– EXCEPTION (optional)
• Actions to perform
when errors occur
– END; (mandatory)
Block Types
Anonymous Procedure Function

[DECLARE] PROCEDURE name FUNCTION name


IS RETURN datatype
IS
BEGIN BEGIN BEGIN
--statements --statements --statements
RETURN value;
[EXCEPTION] [EXCEPTION] [EXCEPTION]

END; END; END;


Create an Anonymous Block
• Enter the anonymous block in the SQL Developer workspace:

DECLARE
V_fname VARCHAR2(20);
BEGIN
SELECT first_name
INTO v_fname
FROM employees
WHERE employee_id=100;
END;
Test the Output of a PL/SQL Block
– Enable output in SQL Developer by clicking the
Enable DBMS Output button on the DBMS Output
tab:

– Use a predefined Oracle package and its procedure:


• DBMS_OUTPUT.PUT_LINE

DBMS_OUTPUT.PUT_LINE(' The First Name of the


Employee is ' || f_name);

Declaring PL/SQL Variables
Topics To Cover
– Recognize valid and invalid identifiers
– List the uses of variables
– Declare and initialize variables
– List and describe various data types
– Identify the benefits of using the %TYPE attribute
– Declare, use, and print bind variables
Use of Variables
• Variables can be used for:
– Temporary storage of data
– Manipulation of stored values
– Reusability

SELECT
first_name,
department_id
INTO Jennifer v_fname
v_fname,
v_deptno
FROM …
10 v_deptno
Requirements for Variable Names
• A variable name:
– Must start with a letter
– Can include letters or numbers
– Can include special characters (such as $, _, and # )
– Must contain no more than 30 characters
– Must not include reserved words
Handling Variables in PL/SQL
• Variables are:
– Declared and initialized in the declarative section
– Used and assigned new values in the executable
section
– Passed as parameters to PL/SQL subprograms
– Used to hold the output of a PL/SQL subprogram
Declaring and Initializing PL/SQL
Variables
• Syntax:
identifier [CONSTANT] datatype [NOT NULL]
[:= | DEFAULT expr];
• Examples:
DECLARE
v_hiredate DATE;
v_deptno NUMBER(2) NOT NULL := 10;
v_location VARCHAR2(13) := 'Atlanta';
c_comm CONSTANT NUMBER := 1400;
Declaring and Initializing PL/SQL
Variables
DECLARE
v_myName VARCHAR2(20);
BEGIN
DBMS_OUTPUT.PUT_LINE('My name is: '|| v_myName);
v_myName := 'John';
1 DBMS_OUTPUT.PUT_LINE('My name is: '|| v_myName);
END;
/
OUTPUT
My name is:
My name is: John
PL/SQL procedure successfully completed.

DECLARE
v_myName VARCHAR2(20):= 'John';
BEGIN
v_myName := 'Steven';
2 DBMS_OUTPUT.PUT_LINE('My name is: '|| v_myName);
END;
/
OUTPUT
My name is: Steven
PL/SQL procedure successfully completed.
Types of Variables
– PL/SQL variables:
• Scalar
• Composite
• Reference
• Large object (LOB)
– Non-PL/SQL variables: Bind variables
Types of Variables
TRUE 25-JAN-13

Pinocchio The Adventures of Pinocchio, by


Carlo Collodi, an Italian writer, and has since
appeared in many adaptations of that story and
others. Carved by a woodcarver named
Geppetto in a small Italian village, he was
created as a wooden puppet but dreamed of
becoming a real boy. He has also been used as a
character who is prone to telling lies and
fabricating stories for various reasons

3.14285714

INDIA
Guidelines for Declaring and Initializing
PL/SQL Variables
– Follow naming conventions.
– Use meaningful identifiers for variables.
– Initialize variables designated as NOT NULL and
CONSTANT.
– Initialize variables with the assignment operator (:=) or
the DEFAULT keyword:
v_myName VARCHAR2(20):='John';

v_myName VARCHAR2(20) DEFAULT 'John';

– Declare one identifier per line for better readability and


code maintenance.
Guidelines for Declaring PL/SQL
Variables
– Avoid using column names as identifiers.
DECLARE
employee_id NUMBER(6);
BEGIN
SELECT employee_id
INTO employee_id
FROM employees
WHERE last_name = 'Kochhar';
END;
/

– Use the NOT NULL constraint when the variable


must hold a value.
Scalar Data Types
– Hold a single value
– Have no internal components

TRUE 25-JAN-13

The soul of the lazy man


desires, and he has nothing;
but the soul of the diligent
shall be made rich.

3.14285714 INDIA
Base Scalar Data Types
– CHAR [(maximum_length)]
– VARCHAR2 (maximum_length)
– NUMBER [(precision, scale)]
– BINARY_INTEGER
– PLS_INTEGER
– BOOLEAN
– BINARY_FLOAT
– BINARY_DOUBLE
Base Scalar Data Types
– DATE
– TIMESTAMP
– TIMESTAMP WITH TIME ZONE
– TIMESTAMP WITH LOCAL TIME ZONE
– INTERVAL YEAR TO MONTH
– INTERVAL DAY TO SECOND
Declaring Scalar Variables
• Examples:

DECLARE
v_emp_job VARCHAR2(9);
v_count_loop BINARY_INTEGER := 0;
v_dept_total_sal NUMBER(9,2) := 0;
v_orderdate DATE := SYSDATE + 7;
c_tax_rate CONSTANT NUMBER(3,2) := 8.25;
v_valid BOOLEAN NOT NULL := TRUE;
...
%TYPE Attribute
– Is used to declare a variable according to:
• A database column definition
• Another declared variable
– Is prefixed with:
• The database table and column
• The name of the declared variable
Declaring Variables
with the %TYPE Attribute
• Syntax
identifier table.column_name%TYPE;

• Examples

...
emp_lname employees.last_name%TYPE;
...

...
balance NUMBER(7,2);
min_balance balance%TYPE := 1000;
...
Declaring Boolean Variables
– Only the TRUE, FALSE, and NULL values can be assigned to
a Boolean variable.
– Conditional expressions use the logical operators AND and OR
and the unary operator NOT to check the variable values.
– The variables always yield TRUE, FALSE, or NULL.
– Arithmetic, character, and date expressions can be used to
return a Boolean value.
Bind Variables
• Bind variables are:
– Created in the environment
– Also called host variables
– Created with the VARIABLE keyword
– Used in SQL statements and PL/SQL blocks
– Accessed even after the PL/SQL block is executed
– Referenced with a preceding colon
Printing Bind Variables
• Example:

VARIABLE b_emp_salary NUMBER


BEGIN
SELECT salary INTO :b_emp_salary
FROM employees WHERE employee_id = 178;
END;
/
PRINT b_emp_salary
SELECT first_name, last_name FROM employees
WHERE salary=:b_emp_salary;
Printing Bind Variables
• Example:

VARIABLE b_emp_salary NUMBER


SET AUTOPRINT ON
DECLARE
v_empno NUMBER(6):=&empno;
BEGIN
SELECT salary INTO :b_emp_salary
FROM employees WHERE employee_id = v_empno;
END;
Output:
7000
LOB Data Type Variables
Book
(CLOB)

Photo
(BLOB)

Movie
(BFILE)

NCLOB
Composite Data Types

TRUE 23-DEC-98 ATLANTA

PL/SQL table structure PL/SQL table structure

1 SMITH 1 5000
2 JONES 2 2345
3 NANCY 3 12
4 TIM 4 3456

VARCHAR2 NUMBER
PLS_INTEGER PLS_INTEGER
THANKS
Writing Executable Statements
Topics To Cover
– Identify lexical units in a PL/SQL block
– Use built-in SQL functions in PL/SQL
– Describe when implicit conversions take place and
when explicit conversions have to be dealt with
– Write nested blocks and qualify variables with
labels
– Write readable code with appropriate indentation
– Use sequences in PL/SQL expressions
Lexical Units in a PL/SQL Block
• Lexical units:
– Are building blocks of any PL/SQL block
– Are sequences of characters including letters,
numerals, tabs, spaces, returns, and symbols
– Can be classified as:
• Identifiers: v_fname, c_percent
• Delimiters: ; , +, -
• Literals: John, 428, True
• Comments: --, /* */
PL/SQL Block Syntax and Guidelines

– Literals
• Character and date literals must be enclosed in single
quotation marks.
• Numbers can be simple values or in scientific notation.
name := 'Henderson';

– Statements can span several lines.


Commenting Code
– Prefix single-line comments with two hyphens (--).
– Place multiple-line comments between the symbols /*
and */.
• Example:
DECLARE
...
v_annual_sal NUMBER (9,2);
BEGIN
/* Compute the annual salary based on the
monthly salary input from the user */
v_annual_sal := monthly_sal * 12;
--The following line displays the annual salary
DBMS_OUTPUT.PUT_LINE(v_annual_sal);
END;
/
SQL Functions in PL/SQL

– Available in procedural statements:


• Single-row functions
– Not available in procedural statements:
• DECODE
• Group functions
SQL Functions in PL/SQL: Examples

– Get the length of a string:


v_statement_size INTEGER(5);
v_statement VARCHAR2(70):='Is Oracle Corporation’’s standard data
access language for relational databases';

-- get the length of the string in prod_description


v_statement_size:= LENGTH(v_statement);

– Get the number of months an employee has worked:

v_tenure:= MONTHS_BETWEEN (CURRENT_DATE, v_hiredate);


Using Sequences in PL/SQL
Expressions
• Starting in 11g:
DECLARE
v_new_id NUMBER;
BEGIN
v_new_id := my_seq.NEXTVAL;
END;
/
• Before 11g:
DECLARE
v_new_id NUMBER;
BEGIN
SELECT my_seq.NEXTVAL INTO v_new_id FROM Dual;
END;
/
X
Data Type Conversion
– Converts data to comparable data types
– Is of two types:
• Implicit conversion
• Explicit conversion
– Functions:
• TO_CHAR
• TO_DATE
• TO_NUMBER
• TO_TIMESTAMP
Data Type Conversion

1 date_of_joining DATE:= '02-Feb-2000';

2 date_of_joining DATE:= 'February 02,2000';

date_of_joining DATE:= TO_DATE('February


3 02,2000','Month DD, YYYY');
Nested Blocks
• PL/SQL blocks can be nested.
– An executable section (BEGIN …
END) can contain nested blocks.
– An exception section can contain
nested blocks. DECLARE
……
BEGIN
…..
DECLARE
……
BEGIN
……
END
…………
END;
Nested Blocks
• Example:

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;
Variable Scope and Visibility
OUTPUT:
DECLARE
Father's Name: Patrick
v_father_name VARCHAR2(20):='Patrick';
v_date_of_birth DATE:='20-Apr-1972'; Date of Birth: 12-DEC-02
BEGIN Child's Name: Mike
DECLARE Date of Birth: 20-APR-72
v_child_name VARCHAR2(20):='Mike';
v_date_of_birth DATE:='12-Dec-2002';
BEGIN
1 DBMS_OUTPUT.PUT_LINE('Father''s Name: '||v_father_name);
DBMS_OUTPUT.PUT_LINE('Date of Birth: '||v_date_of_birth);
DBMS_OUTPUT.PUT_LINE('Child''s Name: '||v_child_name);
2 END;
DBMS_OUTPUT.PUT_LINE('Date of Birth: '||v_date_of_birth);
END;
/
Qualify an Identifier
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;
END;
END outer;
Operators in PL/SQL
– Logical
– Arithmetic
– Concatenation
– Parentheses to control order
of operations
} Same as in SQL

– Exponential operator (**)


Operators in PL/SQL: Examples

– Increment the counter for a loop.


loop_count := loop_count + 1;

– Set the value of a Boolean flag.


good_sal := sal BETWEEN 50000 AND 150000;

– Validate whether an employee number contains a value.

valid := (empno IS NOT NULL);


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
Indenting Code
• For clarity, indent each level of code.
DECLARE
deptno NUMBER(4);
BEGIN
location_id NUMBER(4);
IF x=0 THEN
BEGIN
y:=1;
SELECT department_id,
END IF;
location_id
END;
INTO deptno,
/
location_id
FROM departments
WHERE department_name
= 'Sales';
...
END;
/
THANKS
Interacting with the Oracle
Database Server
Topics To Cover
– Determine the SQL statements that can be directly
included in a PL/SQL executable block
– Manipulate data with DML statements in PL/SQL
– Use transaction control statements in PL/SQL
– Make use of the INTO clause to hold the values
returned by a SQL statement
– Differentiate between implicit cursors and explicit
cursors
– Use SQL cursor attributes
SQL Statements in PL/SQL
– Retrieve a row from the database by using the
SELECT command.
– Make changes to rows in the database by using
DML commands.
– Control a transaction with the COMMIT,
ROLLBACK, or SAVEPOINT command.
SELECT Statements in PL/SQL
• Retrieve data from the database with a SELECT statement.
• Syntax:

SELECT select_list
INTO {variable_name[, variable_name]...
| record_name}
FROM table
[WHERE condition];
SELECT Statements in PL/SQL
– The INTO clause is required.
– Queries must return only one row.
• Example:

DECLARE
v_fname VARCHAR2(25);
BEGIN
SELECT first_name INTO v_fname
FROM employees WHERE employee_id=200;
DBMS_OUTPUT.PUT_LINE(' First Name is : '||v_fname);
END;
/
Retrieving Data in PL/SQL
• Retrieve hire_date and salary for the specified employee.
• Example:

DECLARE
v_emp_hiredate employees.hire_date%TYPE;
v_emp_salary employees.salary%TYPE;
BEGIN
SELECT hire_date, salary
INTO v_emp_hiredate, v_emp_salary
FROM employees
WHERE employee_id = 100;
END;
/
Retrieving Data in PL/SQL
• Return the sum of the salaries for all the employees in
the specified department.
• Example:

DECLARE
v_sum_sal NUMBER(10,2);
v_deptno NUMBER NOT NULL := 60;
BEGIN
SELECT SUM(salary) -- group function
INTO v_sum_sal FROM employees
WHERE department_id = v_deptno;
DBMS_OUTPUT.PUT_LINE ('The sum of salary is ' || v_sum_sal);
END;
Naming Conventions
• DECLARE
• hire_date employees.hire_date%TYPE;
• sysdate hire_date%TYPE;
• employee_id employees.employee_id%TYPE := 176;
• BEGIN
• SELECT hire_date, sysdate
• INTO hire_date, sysdate
• FROM employees
• WHERE employee_id = employee_id;
• END;
• /
Naming Conventions
– Use a naming convention to avoid ambiguity in the
WHERE clause.
– Avoid using database column names as identifiers.
– Syntax errors can arise because PL/SQL checks the
database first for a column in the table.
– The names of local variables and formal parameters
take precedence over the names of database tables.
– The names of database table columns take
precedence over the names of local variables.
Using PL/SQL to Manipulate Data
• Make changes to database tables by using DML commands:
– INSERT
– UPDATE
– DELETE
– MERGE DELETE

INSERT

MERGE
UPDATE
Inserting Data
• Add new employee information to the EMPLOYEES table.
• Example:

BEGIN
INSERT INTO employees
(employee_id, first_name, last_name, email,
hire_date, job_id, salary)
VALUES(employees_seq.NEXTVAL, 'Ruth', 'Cores',
'RCORES',CURRENT_DATE, 'AD_ASST', 4000);
END;
/
Updating Data
• Increase the salary of all employees who are stock clerks.
• Example:

DECLARE
sal_increase employees.salary%TYPE := 800;
BEGIN
UPDATE employees
SET salary = salary + sal_increase
WHERE job_id = 'ST_CLERK';
END;
/
Deleting Data
• Delete rows that belong to department 10 from the
employees table.
• Example:

DECLARE
deptno employees.department_id%TYPE := 10;
BEGIN
DELETE FROM employees
WHERE department_id = deptno;
END;
/
Merging Rows
• Insert or update rows in the copy_emp table to match the
employees table.

BEGIN
MERGE INTO copy_emp c
USING employees e
ON (e.employee_id = c.empno)
WHEN MATCHED THEN
UPDATE SET
c.first_name = e.first_name,
c.last_name = e.last_name,
c.email = e.email,
. . .
WHEN NOT MATCHED THEN
INSERT VALUES(e.employee_id, e.first_name, e.last_name,
. . .,e.department_id);
END;
/
SQL Cursor
– A cursor is a pointer to the private memory area
allocated by the Oracle server.
– A cursor is used to handle the result set of a
SELECT statement.
– There are two types of cursors:
• Implicit: Created and managed internally by the Oracle
server to process SQL statements
• Explicit: Declared explicitly by the programmer
SQL Cursor Attributes for Implicit
Cursors
• Using SQL cursor attributes, you can test the outcome of your
SQL statements.

SQL%FOUND Boolean attribute that evaluates to TRUE if the


most recent SQL statement returned at least one
row
SQL%NOTFOUND Boolean attribute that evaluates to TRUE if
the most recent SQL statement did not
return even one row
SQL%ROWCOUNT An integer value that represents the number of
rows affected by the most recent SQL statement
SQL Cursor Attributes for Implicit
Cursors
• Delete rows that have the specified employee ID from the
employees table. Print the number of rows deleted.
• Example:

DECLARE
v_rows_deleted VARCHAR2(30)
v_empno employees.employee_id%TYPE := 176;
BEGIN
DELETE FROM employees
WHERE employee_id = v_empno;
v_rows_deleted := (SQL%ROWCOUNT ||
' row deleted.');
DBMS_OUTPUT.PUT_LINE (v_rows_deleted);

END;
THANKS
Writing Control Structures
Topics To Cover
– Identify the uses and types of control structures
– Construct an IF statement
– Use CASE statements and CASE expressions
– Construct and identify loop statements
– Use guidelines when using conditional control
structures
Controlling Flow of Execution

for
. .
loop
. .
.
while
IF Statement
• Syntax:

IF condition THEN
statements;
[ELSIF condition THEN
statements;]
[ELSE
statements;]
END IF;
Simple IF Statement

DECLARE
v_myage number:=31;
BEGIN
IF v_myage < 11
THEN
DBMS_OUTPUT.PUT_LINE(' I am a child ');
END IF;
END;
/

• Output:
IF THEN ELSE Statement
DECLARE
v_myage number:=31;
BEGIN
IF v_myage < 11
THEN
DBMS_OUTPUT.PUT_LINE(' I am a child ');
ELSE
DBMS_OUTPUT.PUT_LINE(' I am not a child ');
END IF;
END;
/

• Output:
DECLARE
IF ELSIF ELSE Clause
v_myage number:=31;
BEGIN
IF v_myage < 11 THEN
DBMS_OUTPUT.PUT_LINE(' I am a child ');
ELSIF v_myage < 20 THEN
DBMS_OUTPUT.PUT_LINE(' I am young ');
ELSIF v_myage < 30 THEN
DBMS_OUTPUT.PUT_LINE(' I am in my twenties');
ELSIF v_myage < 40 THEN
DBMS_OUTPUT.PUT_LINE(' I am in my thirties');
ELSE
DBMS_OUTPUT.PUT_LINE(' I am always young ');
END IF;
END;
/
Output:
NULL Value in IF Statement

DECLARE
v_myage number;
BEGIN
IF v_myage < 11 THEN
DBMS_OUTPUT.PUT_LINE(' I am a child ');
ELSE
DBMS_OUTPUT.PUT_LINE(' I am not a child ');
END IF;
END;
/
CASE Expressions
– A CASE expression selects a result and returns it.
– To select the result, the CASE expression uses
expressions. The value returned by these expressions is
used to select one of several alternatives.
CASE selector
WHEN expression1 THEN result1
WHEN expression2 THEN result2
...
WHEN expressionN THEN resultN
[ELSE resultN+1]
END;
/
CASE Expressions: Example
SET VERIFY OFF
DECLARE
v_grade CHAR(1) := UPPER('&grade');
appraisal VARCHAR2(20);
BEGIN
appraisal := CASE v_grade
WHEN 'A' THEN 'Excellent'
WHEN 'B' THEN 'Very Good'
WHEN 'C' THEN 'Good'
ELSE 'No such grade'
END;
DBMS_OUTPUT.PUT_LINE ('Grade: '|| v_grade || '
Appraisal ' || appraisal);
END;
/
Searched CASE Expressions
DECLARE
v_grade CHAR(1) := UPPER('&grade');
appraisal VARCHAR2(20);
BEGIN
appraisal := CASE
WHEN v_grade = 'A' THEN 'Excellent'
WHEN v_grade IN ('B','C') THEN 'Good'
ELSE 'No such grade'
END;
DBMS_OUTPUT.PUT_LINE ('Grade: '|| v_grade || '
Appraisal ' || appraisal);
END;
/
CASE Statement
DECLARE
v_deptid NUMBER;
v_deptname VARCHAR2(20);
v_emps NUMBER;
v_mngid NUMBER:= 108;
BEGIN
CASE v_mngid
WHEN 108 THEN
SELECT department_id, department_name
INTO v_deptid, v_deptname FROM departments
WHERE manager_id=108;
SELECT count(*) INTO v_emps FROM employees
WHERE department_id=v_deptid;
WHEN 200 THEN
...
END CASE;
DBMS_OUTPUT.PUT_LINE ('You are working in the '|| deptname||
' department. There are '||v_emps ||' employees in this
department');
END;
/
Handling Nulls
• When working with nulls, you can avoid some
common mistakes by keeping in mind the following
rules:
– Simple comparisons involving nulls always yield NULL.
– Applying the logical operator NOT to a null yields NULL.
– If the condition yields NULL in conditional control
statements, its associated sequence of statements is not
executed.
Logic Tables
• Build a simple Boolean condition with a
comparison
AND operator.
TRUE FALSE NULL OR TRUE FALSE NULL NOT

TRUE TRUE FALSE NULL TRUE TRUE TRUE TRUE TRUE FALSE

FALSE FALSE FALSE FALSE FALSE TRUE FALSE NULL FALSE TRUE

NULL NULL FALSE NULL NULL TRUE NULL NULL NULL NULL
Boolean Conditions
• What is the value of flag in each case?

flag := reorder_flag AND available_flag;

REORDER_FLAG AVAILABLE_FLAG FLAG

TRUE TRUE ? (1)

TRUE FALSE ? (2)

NULL TRUE ? (3)

NULL FALSE ? (4)


Iterative Control: LOOP Statements
– Loops repeat a statement (or sequence of
statements) multiple times.
– There are three loop types:
• Basic loop
• FOR loop
• WHILE loop
Basic Loops
• Syntax:
LOOP
statement1;
. . .
EXIT [WHEN condition];
END LOOP;
Basic Loops
• Example:

DECLARE
v_countryid locations.country_id%TYPE := 'CA';
v_loc_id locations.location_id%TYPE;
v_counter NUMBER(2) := 1;
v_new_city locations.city%TYPE := 'Montreal';
BEGIN
SELECT MAX(location_id) INTO v_loc_id FROM locations
WHERE country_id = v_countryid;
LOOP
INSERT INTO locations(location_id, city, country_id)
VALUES((v_loc_id + v_counter), v_new_city, v_countryid);
v_counter := v_counter + 1;
EXIT WHEN v_counter > 3;
END LOOP;
END;
/
WHILE Loops
• Syntax:
WHILE condition LOOP
statement1;
statement2;
. . .
END LOOP;
• Use the WHILE loop to repeat statements while a
condition is TRUE.
WHILE Loops
• Example
DECLARE
v_countryid locations.country_id%TYPE := 'CA';
v_loc_id locations.location_id%TYPE;
v_new_city locations.city%TYPE := 'Montreal';
v_counter NUMBER := 1;
BEGIN
SELECT MAX(location_id) INTO v_loc_id FROM locations
WHERE country_id = v_countryid;
WHILE v_counter <= 3 LOOP
INSERT INTO locations(location_id, city, country_id)
VALUES((v_loc_id + v_counter), v_new_city, v_countryid);
v_counter := v_counter + 1;
END LOOP;
END;
/
FOR Loops
– Use a FOR loop to shortcut the test for the number of
iterations.
– Do not declare the counter; it is declared implicitly.

FOR counter IN [REVERSE]


lower_bound..upper_bound LOOP
statement1;
statement2;
. . .
END LOOP;
FOR Loops
• Example:

DECLARE
v_countryid locations.country_id%TYPE := 'CA';
v_loc_id locations.location_id%TYPE;
v_new_city locations.city%TYPE := 'Montreal';
BEGIN
SELECT MAX(location_id) INTO v_loc_id
FROM locations
WHERE country_id = v_countryid;
FOR i IN 1..3 LOOP
INSERT INTO locations(location_id, city, country_id)
VALUES((v_loc_id + i), v_new_city, v_countryid );
END LOOP;
END;
/
FOR Loops
• Guidelines
– Reference the counter within the loop only; it is undefined
outside the loop.
– Do not reference the counter as the target of an assignment.
– Neither loop bound should be NULL.
Guidelines for Loops
– Use the basic loop when the statements inside the loop
must execute at least once.
– Use the WHILE loop if the condition must be evaluated
at the start of each iteration.
– Use a FOR loop if the number of iterations is known.
Nested Loops and Labels
– You can nest loops to multiple levels.
– Use labels to distinguish between blocks and
loops.
– Exit the outer loop with the EXIT statement
that references the label.
Nested Loops and Labels
...
BEGIN
<<Outer_loop>>
LOOP
v_counter := v_counter+1;
EXIT WHEN v_counter>10;
<<Inner_loop>>
LOOP
...
EXIT Outer_loop WHEN total_done = 'YES';
-- Leave both loops
EXIT WHEN inner_done = 'YES';
-- Leave inner loop only
...
END LOOP Inner_loop;
...
END LOOP Outer_loop;
END;
/
PL/SQL CONTINUE Statement
– Definition
• Adds the functionality to begin the next loop
iteration
• Provides programmers with the ability to transfer
control to the next iteration of a loop
• Uses parallel structure and semantics to the EXIT
statement
– Benefits
• Eases the programming process
• May see a small performance improvement over the
previous programming workarounds to simulate the
CONTINUE statement
PL/SQL CONTINUE Statement:
Example
anonymous block completed
DECLARE
Total is: 1
v_total SIMPLE_INTEGER := 0;
Out of Loop Total is: 2
BEGIN
Total is: 4
FOR i IN 1..10 LOOP
Out of Loop Total is: 6
1 v_total := v_total + i; Total is: 9
dbms_output.put_line
Out of Loop Total is: 12
('Total is: '|| v_total);
Total is: 16
CONTINUE WHEN i > 5;
Out of Loop Total is: 20
v_total := v_total + i;
Total is: 25
2 dbms_output.put_line Out of Loop Total is: 30
('Out of Loop Total is:
Total is: 36
'|| v_total);
Total is: 43
END LOOP;
Total is: 51
END;
Total is: 60
/
Total is: 70
THANKS
Working with
Composite Data Types
Topics To Cover
– Create user-defined PL/SQL records
– Create a record with the %ROWTYPE attribute
– Create an INDEX BY table
– Create an INDEX BY table of records
– Varray,Nested table
– Describe the differences between Index by
Table,Varray,Nested Table.
Composite Data Types
– Can hold multiple values (unlike scalar types)
– Are of two types:
• PL/SQL records
• PL/SQL collections
– INDEX BY tables or associative arrays
– Nested table
– VARRAY
Composite Data Types
– Use PL/SQL records when you want to store values of
different data types but only one occurrence at a time.
– Use PL/SQL collections when you want to store values of
the same data type.
PL/SQL Records
– Must contain one or more components (called fields) of
any scalar, RECORD, or INDEX BY table data type
– Are similar to structures in most third-generation
languages (including C and C++)
– Are user defined and can be a subset of a row in a table
– Treat a collection of fields as a logical unit
– Are convenient for fetching a row of data from a table
for processing
Creating a PL/SQL Record
• Syntax:
1 TYPE type_name IS RECORD
(field_declaration[, field_declaration]…);

2 identifier type_name;

field_declaration:
field_name {field_type | variable%TYPE
| table.column%TYPE | table%ROWTYPE}
[[NOT NULL] {:= | DEFAULT} expr]
Creating a PL/SQL Record
• Declare variables to store the name, job, and salary of a
new employee.
• Example:
DECLARE
type t_rec 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;
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;
PL/SQL Record Structure

Field1 (data type) Field2 (data type) Field3 (data type)

Example:

Field1 (data type) Field2 (data type) Field3 (data type)


employee_id number(6) last_name varchar2(25) job_id varchar2(10)

100 King AD_PRES


%ROWTYPE Attribute
– Declare a variable according to a collection of columns
in a database table or view.
– Prefix %ROWTYPE with the database table or view.
– Fields in the record take their names and data types
from the columns of the table or view.
• Syntax:

DECLARE
identifier reference%ROWTYPE;
Advantages of Using %ROWTYPE
– The number and data types of the underlying
database columns need not be known—and, in fact,
might change at run time.
– The %ROWTYPE attribute is useful when retrieving
a row with the SELECT * statement.
%ROWTYPE Attribute: Example
DECLARE
v_employee_number number:= 124;
v_emp_rec employees%ROWTYPE;
BEGIN
SELECT * INTO v_emp_rec FROM employees
WHERE employee_id = v_employee_number;
INSERT INTO retired_emps(empno, ename, job, mgr,
hiredate, leavedate, sal, comm, deptno)
VALUES (v_emp_rec.employee_id, v_emp_rec.last_name,
v_emp_rec.job_id, v_emp_rec.manager_id,
v_emp_rec.hire_date, SYSDATE,
v_emp_rec.salary, v_emp_rec.commission_pct,
v_emp_rec.department_id);
END;
/
Inserting a Record
by Using %ROWTYPE
...
DECLARE
v_employee_number number:= 124;
v_emp_rec retired_emps%ROWTYPE;
BEGIN
SELECT employee_id, last_name, job_id, manager_id,
hire_date, hire_date, salary, commission_pct,
department_id INTO v_emp_rec FROM employees
WHERE employee_id = v_employee_number;
INSERT INTO retired_emps VALUES v_emp_rec;
END;
/
SELECT * FROM retired_emps;
Updating a Row in a Table
by Using a Record
SET VERIFY OFF
DECLARE
v_employee_number number:= 124;
v_emp_rec retired_emps%ROWTYPE;
BEGIN
SELECT * INTO v_emp_rec FROM retired_emps;
v_emp_rec.leavedate:=CURRENT_DATE;
UPDATE retired_emps SET ROW = v_emp_rec WHERE
empno=v_employee_number;
END;
/
SELECT * FROM retired_emps;
INDEX BY Tables or Associative
Arrays
– Are PL/SQL structures with two columns:
• Primary key of integer or string data type
• Column of scalar or record data type
– Are unconstrained in size. However, the size
depends on the values that the key data type can
hold.
– Local index tables in the form of an array
– Arbitrary numbers or strings can be used as
subscript values
– These can not be stored inside the database
Creating an INDEX BY Table
• Syntax:
TYPE type_name IS TABLE OF
{column_type | variable%TYPE
| table.column%TYPE} [NOT NULL]
| table%ROWTYPE
[INDEX BY PLS_INTEGER | BINARY_INTEGER
| VARCHAR2(<size>)];
identifier type_name;

...
TYPE ename_table_type IS TABLE OF
• Declare an INDEX BY table to store the
employees.last_name%TYPE
INDEX BY PLS_INTEGER;
last names of employees:
...
ename_table ename_table_type;
INDEX BY Table Structure

Unique key Value


... ...

1 Jones
5 Smith
3 Maduro

... ...

PLS_INTEGER Scalar
Declaring Index by Table in an Anonymous
block: Example
DECLARE
-- Declaring a simple Index by table of number
TYPE my_plsql_tab IS TABLE OF NUMBER
INDEX BY BINARY_INTEGER ;
-- Creating a variable of PLSQL Table (my_tab) type
t_type my_plsql_tab ;

BEGIN
FOR i IN 1 .. 10
LOOP
-- Initializing Array
t_type(i) := i ;
END LOOP ;

FOR i IN 1 .. 10
LOOP
-- Accessing array elements
DBMS_OUTPUT.PUT_LINE(t_type(i)) ;
END LOOP ;
END ;
Creating an INDEX BY Table
• DECLARE
• TYPE ename_table_type IS TABLE OF
• employees.last_name%TYPE
• INDEX BY PLS_INTEGER;
• TYPE hiredate_table_type IS TABLE OF DATE
• INDEX BY PLS_INTEGER;
• ename_table ename_table_type;
• hiredate_table hiredate_table_type;
• BEGIN
• ename_table(1) := 'CAMERON';
• hiredate_table(8) := SYSDATE + 7;
• IF ename_table.EXISTS(1) THEN
• INSERT INTO ...
• ...
• END;
• /
INDEX BY Table of Records
• Define an INDEX BY table variable to hold
an entire row from a table.
•DECLARE
Example:
TYPE dept_table_typeIS TABLE OF
departments%ROWTYPE
INDEX BY VARCHAR2(20);
dept_table dept_table_type;
-- Each element of dept_table is a record
INDEX BY Table of Records:
Example
DECLARE
TYPE emp_table_type IS TABLE OF
employees%ROWTYPE INDEX BY PLS_INTEGER;
my_emp_table emp_table_type;
max_count NUMBER(3):= 104;
BEGIN
FOR i IN 100..max_count
LOOP
SELECT * INTO my_emp_table(i) FROM employees
WHERE employee_id = i;
END LOOP;
FOR i IN my_emp_table.FIRST..my_emp_table.LAST
LOOP
DBMS_OUTPUT.PUT_LINE(my_emp_table(i).last_name);
END LOOP;
END;
/
Nested Tables
1 Bombay
2 Sydney
3 Oxford
4 London
.. ....
Collection type – Nested Tables
• Nested tables
– Hold an arbitrary number of elements
– They use sequential numbers as subscripts
– Can be stored in database tables
– Can be manipulated through SQL

• SYNTAX
TYPE type_name IS TABLE OF element_type
[NOT NULL];
Declaring Nested Table in an Anonymous
block: Example
DECLARE
-- Declaring a nested table collection type

TYPE nested_table_type IS TABLE OF VARCHAR2(20);

-- Declaring a variable of nested table type

t_nt_var nested_table_type ;

BEGIN
-- Initializing Array
t_nt_var := nested_table_type( 'Shipping', 'Sales',
'Finance' , 'Payroll' );
-- Accessing array elements
FOR j IN 1 .. 4
LOOP
DBMS_OUTPUT.PUT_LINE(t_nt_var(j));
END LOOP;
END;
VARRAY
A variable-size array (VARRAY) is similar to a PL/SQL
table, except that a VARRAY is constrained in size.

1 Bombay
2 Sydney
3 Oxford
4 London
.. ....
10 Tokyo
Collection Type - Varrays
• Varrays (variable-size arrays)
• Uses sequential numbers as subscripts
• Cannot remove/delete individual elements from the array
• Length defined at design time can be manipulated at runtime;
However not beyond the max size specified in declaration
• Can be stored and retrieved through SQL
• Less flexible than nested tables
• Syntax:
TYPE type_name IS VARRAY(max_size) OF element data_type;
• Max_size is the maximum no of elements to be allowed for the
array
• Element_data_type is the Data Type of the elements
• Varrays can be used:
– In an Anonymous block
– In database along with various DML commands and method usage
Varrays in an Anonymous Block:
Example
DECLARE
TYPE t_names IS VARRAY(5) OF VARCHAR2(20);

v_name_list t_names :=

t_names('Amit','Summet','Rajesh','Milind','Sachin'
);

BEGIN
FOR cnt IN 1 .. v_name_list.count
LOOP
DBMS_OUTPUT.PUT_LINE('Name :'||
v_name_list(cnt));
END LOOP;
END;
Methods In Collection
• Various methods available for collections are:
– Exists(n): Returns TRUE if nth element exists in Varray
– Count: Returns the number of elements in the Varray
– Limit: Gives the Maximum size of the array
– First & Last: Returns the First and Last index number in
the collection
– Extend(n): Increases the size of collection by n. Appends
n elements to a collection
– Delete(n): Removes an element form nth index
– Trim(n): Removes last n elements from the Collection
DIFFERENCES BETWEEN COLLECTIONS
Thanks
THANKS
Handling Exceptions
Topics To Cover
– Define PL/SQL exceptions
– Recognize unhandled exceptions
– List and use different types of PL/SQL exception
handlers
– Trap unanticipated errors
– Describe the effect of exception propagation in
nested blocks
– Customize PL/SQL exception messages
Example of an Exception
DECLARE
v_lname VARCHAR2(15);
BEGIN
SELECT last_name INTO v_lname
FROM employees
WHERE first_name='John';
DBMS_OUTPUT.PUT_LINE ('John''s last name is :'
||v_lname);
END;
Example of an Exception
DECLARE
v_lname VARCHAR2(15);
BEGIN
SELECT last_name INTO v_lname
FROM employees
WHERE first_name='John';
DBMS_OUTPUT.PUT_LINE ('John''s last name is :'
||v_lname);
EXCEPTION
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE (' Your select statement
retrieved multiple rows. Consider using a
cursor.');
END;
/
Handling Exceptions with PL/SQL
– An exception is a PL/SQL error that is raised during
program execution.
– An exception can be raised:
• Implicitly by the Oracle server
• Explicitly by the program
– An exception can be handled:
• By trapping it with a handler
• By propagating it to the calling environment
Handling Exceptions

DECLAR
……. Is the
BEGIN
exception Terminate
……. No abruptly.
…….
trapped?

Yes

Exception Execute statements Propagate the


is raised. in the EXCEPTION exception.
section.

Terminate
gracefully.
Exception Types
– Predefined Oracle server
– Non-predefined Oracle server
} Implicitly raised

– User-defined ------------> Explicitly raised


Trapping Exceptions
• Syntax:
EXCEPTION
WHEN exception1 [OR exception2 . . .] THEN
statement1;
statement2;
. . .
[WHEN exception3 [OR exception4 . . .] THEN
statement1;
statement2;
. . .]
[WHEN OTHERS THEN
statement1;
statement2;
. . .]
Guidelines for Trapping Exceptions
– The EXCEPTION keyword starts the exception-handling
section.
– Several exception handlers are allowed.
– Only one handler is processed before leaving the block.
– WHEN OTHERS is the last clause.
Trapping Predefined Oracle Server
Errors
– Reference the predefined name in the exception-
handling routine.
– Sample predefined exceptions:
• NO_DATA_FOUND
• TOO_MANY_ROWS
• INVALID_CURSOR
• ZERO_DIVIDE
• DUP_VAL_ON_INDEX
Trapping Non-Predefined
Oracle Server Errors

Declare Associate Reference

Declarative section EXCEPTION section

Name the Use PRAGMA Handle the raised


exception. EXCEPTION_INIT. exception.
Non-Predefined Error
• To trap Oracle server error number –01400
(“cannot insert NULL”):
DECLARE
e_insert_excep EXCEPTION; 1
PRAGMA EXCEPTION_INIT(e_insert_excep, -01400); 2
BEGIN
INSERT INTO departments
(department_id, department_name) VALUES (280, NULL);
EXCEPTION 3
WHEN e_insert_excep THEN
DBMS_OUTPUT.PUT_LINE('INSERT OPERATION FAILED');
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/
Functions for Trapping Exceptions
– SQLCODE: Returns the numeric value for the error code
– SQLERRM: Returns the message associated with the
error number
Functions for Trapping Exceptions
• Example
DECLARE
error_code NUMBER;
error_message VARCHAR2(255);
BEGIN
...
EXCEPTION
...
WHEN OTHERS THEN
ROLLBACK;
error_code := SQLCODE ;
error_message := SQLERRM ;
INSERT INTO errors (e_user, e_date, error_code,
error_message) VALUES(USER,SYSDATE,error_code,
error_message);
END;
/
Trapping User-Defined Exceptions

Declare Raise Reference

Declarative Executable Exception-handling


section section section

Name the Explicitly raise Handle the raised


exception. the exception by exception.
using the RAISE
statement.
Trapping User-Defined Exceptions
DECLARE
v_deptno NUMBER := 500;
v_name VARCHAR2(20) := 'Testing';
e_invalid_department EXCEPTION;
BEGIN
1
UPDATE departments
SET department_name = v_name
WHERE department_id = v_deptno;
IF SQL % NOTFOUND THEN
RAISE e_invalid_department;
2
END IF;
COMMIT;
EXCEPTION 3
WHEN e_invalid_department THEN
DBMS_OUTPUT.PUT_LINE('No such department id.');
END;
/
Propagating Exceptions in a Subblock
DECLARE
. . .
e_no_rows exception;
e_integrity exception;
PRAGMA EXCEPTION_INIT (e_integrity, -2292);
BEGIN
FOR c_record IN emp_cursor LOOP
BEGIN
Subblocks can handle
SELECT ...
an exception or pass UPDATE ...
the exception to the IF SQL%NOTFOUND THEN
enclosing block. RAISE e_no_rows;
END IF;
END;
END LOOP;
EXCEPTION
WHEN e_integrity THEN ...
WHEN e_no_rows THEN ...
END;
/
RAISE_APPLICATION_ERROR
Procedure
• Syntax:
raise_application_error (error_number,
message[, {TRUE | FALSE}]);

– You can use this procedure to issue user-defined


error messages from stored subprograms.
– You can report errors to your application and
avoid returning unhandled exceptions.
RAISE_APPLICATION_ERROR
Procedure

– Used in two different places:


• Executable section
• Exception section
– Returns error conditions to the user in a
manner consistent with other Oracle server
errors
RAISE_APPLICATION_ERROR
Procedure
• Executable section:
BEGIN
...
DELETE FROM employees
WHERE manager_id = v_mgr;
IF SQL%NOTFOUND THEN
RAISE_APPLICATION_ERROR(-20202,
'This is not a valid manager');
END IF;
...

...
EXCEPTION
WHEN NO_DATA_FOUND THEN
• Exception section:
RAISE_APPLICATION_ERROR (-20201,
'Manager is not a valid employee.');
END;
/
THANKS
Creating Stored Procedures and
Functions
Topics To Cover
– Differentiate between anonymous blocks and
subprograms
– Create a simple procedure and invoke it from an
anonymous block
– Create a simple function
– Create a simple function that accepts a parameter
– Differentiate between procedures and functions
Procedures and Functions
– Are named PL/SQL blocks
– Are called PL/SQL subprograms
– Have block structures similar to anonymous blocks:
• Optional declarative section (without the DECLARE keyword)
• Mandatory executable section
• Optional section to handle exceptions
Differences Between Anonymous
Blocks and Subprograms
Anonymous Blocks Subprograms
Unnamed PL/SQL blocks Named PL/SQL blocks

Compiled every time Compiled only once

Not stored in the database Stored in the database

Cannot be invoked by other Named and, therefore, can be invoked by


applications other applications
Do not return values Subprograms called functions must return
values.

Cannot take parameters Can take parameters


Procedure: Syntax
CREATE [OR REPLACE] PROCEDURE procedure_name
[(argument1 [mode1] datatype1,
argument2 [mode2] datatype2,
. . .)]
IS|AS
procedure_body;
Procedure: Example
...
CREATE TABLE dept AS SELECT * FROM departments;
CREATE PROCEDURE add_dept IS
v_dept_id dept.department_id%TYPE;
v_dept_name dept.department_name%TYPE;
BEGIN
v_dept_id:=280;
v_dept_name:='ST-Curriculum';
INSERT INTO dept(department_id,department_name)
VALUES(v_dept_id,v_dept_name);
DBMS_OUTPUT.PUT_LINE(' Inserted '|| SQL%ROWCOUNT
||' row ');
END;
Invoking the Procedure
BEGIN
add_dept;
END;
/
SELECT department_id, department_name FROM dept
WHERE department_id=280;
Function: Syntax
CREATE [OR REPLACE] FUNCTION function_name
[(argument1 [mode1] datatype1,
argument2 [mode2] datatype2,
. . .)]
RETURN datatype
IS|AS
function_body;
Function: Example
CREATE FUNCTION check_sal RETURN Boolean IS
v_dept_id employees.department_id%TYPE;
v_empno employees.employee_id%TYPE;
v_sal employees.salary%TYPE;
v_avg_sal employees.salary%TYPE;
BEGIN
v_empno:=205;
SELECT salary,department_id INTO v_sal,v_dept_id FROM
employees
WHERE employee_id= v_empno;
SELECT avg(salary) INTO v_avg_sal FROM employees WHERE
department_id=v_dept_id;
IF v_sal > v_avg_sal THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL;
END;
Invoking the Function
BEGIN
IF (check_sal IS NULL) THEN
DBMS_OUTPUT.PUT_LINE('The function returned
NULL due to exception');
ELSIF (check_sal) THEN
DBMS_OUTPUT.PUT_LINE('Salary > average');
ELSE
DBMS_OUTPUT.PUT_LINE('Salary < average');
END IF;
END;
/
Passing a Parameter to the Function
DROP FUNCTION check_sal;
CREATE FUNCTION check_sal(p_empno employees.employee_id%TYPE)
RETURN Boolean IS
v_dept_id employees.department_id%TYPE;
v_sal employees.salary%TYPE;
v_avg_sal employees.salary%TYPE;
BEGIN
SELECT salary,department_id INTO v_sal,v_dept_id FROM employees
WHERE employee_id=p_empno;
SELECT avg(salary) INTO v_avg_sal FROM employees
WHERE department_id=v_dept_id;
IF v_sal > v_avg_sal THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
EXCEPTION
...
Invoking the Function with a
Parameter
BEGIN
DBMS_OUTPUT.PUT_LINE('Checking for employee with id 205');
IF (check_sal(205) IS NULL) THEN
DBMS_OUTPUT.PUT_LINE('The function returned
NULL due to exception');
ELSIF (check_sal(205)) THEN
DBMS_OUTPUT.PUT_LINE('Salary > average');
ELSE
DBMS_OUTPUT.PUT_LINE('Salary < average');
END IF;
DBMS_OUTPUT.PUT_LINE('Checking for employee with id 70');
IF (check_sal(70) IS NULL) THEN
DBMS_OUTPUT.PUT_LINE('The function returned
NULL due to exception');
ELSIF (check_sal(70)) THEN
...
END IF;
END;
/
THANKS
Working with Packages

13-165
Topics To cover
• Package – Concept
• Package – Specification
• Package – Body
Package – Concept
• Package is schema object that groups logically
related plsql types, item and subprograms.

• Packages provide encapsulation that keeps


related procedures and functions together in
the database.

• Packages help to keep code routines properly


organized.
Package – Concept

• Group of related procedures and functions are


together kept in package and stored in Database.

• Oracle provides with Several Built In packages .

• We can develop our own packages according to our


business requirements.
Package – Concept
• All objects (procedures and functions) within a
package are parsed, compiled, and loaded into
memory together - this helps to improve
performance.

• Packages are also pre-compiled and stored in the


database and can be called by other programs just the
way Procedures and Functions are stored and used.
Package – Concept
• We can store procedures and functions directly in
database or we can put them in package and store
that package in database.

• Advantage of putting database objects in package are:


– They are well organized
– Easy to maintain
– Entire package is loaded in the memory .
Package – Concept
• Benefits of package:

• Information hiding (Private functions and procedures).

• Object-oriented design (Related procedures and


functions group together).

• Top-down design. ( Package is developed and


designed in two parts ).
Package – Concept

• In Oracle by default user has the privilege to


use procedure , function and package created
in their own user account.

• To use procedure , function and packages of


other user’s you need to have the privileges.
Package – Concept
• A package consists of two parts:

– Package specification
– Package body

• First specification is created and compiled.

• Body is created and compiled after specification.

• Whenever we change specification or body it is advisable to


compile both specification and body again.
Package Specification
• It consist of following things:
– Declaration of variables, cursors, procedures, functions,
Types, Exceptions.

• In specification we do not write code for any


procedure and function we only declare the name and
parameters for them , code is always written in the
package body.
Package Specification
• We only declare variables, type , exceptions and cursors here
but they are actually used in body.

• In body we may or may not have other procedure and


function but any procedure or function which is declared in
specification:

1. It should be defined with the code in the same order


in the body.

2. Only procedure and functions which are there in


specification can be used by other external program.
Package Specification
• In other words procedures and functions in
specification are public and can be used by
other programs

• Procedure and functions not in specification


but are there in body are private and can be
used only inside the package body not from
outside by any other program.
Package Specification
• Syntax: Creating package specification

CREATE or REPLACE Package Package_Name


AS
<Types>
<Declare variables>
<Declare Cursor>
<Declare Exceptions>
<Declaration of Procedures , Functions>
END Package_Name;
Package Specification
• Example: Creating package specification

CREATE or REPLACE Package EMPPackage


AS
Type t_Ename IS Varchar2(25);
V_empno Emp.Empno%type;
v_ename t_Ename;
Cursor C_Emp IS
Select * from Emp;
Procedure CalculateBonus(p_deptno Number);
Procedure UpdateSalary(p_empno Number, p_sal Number) ;
Function GetSalary(p_empno Number) Return Number;
END EMPPackage;
Package Body
• It consist of following things:
– Definition or Code for all procedures and functions
declared in specification. The name, parameter and return
type should be exactly same as given in specification

– Private procedure and functions i.e. those which are not


declared in specification and can be used only inside
package body only.

– All Procedure and Function inside body can use the variable,
types , exception and cursors declared in specification.
Package Body
• Syntax: Creating package Body

CREATE or REPLACE Package Body Package_Name


AS
<Private Variables>
<Private cursors>
<Private procedures and Functions>
<Definition of all the procedures and functions declared in
specification>
END Package_Name;
Package Body
• Example: Creating package Body
CREATE or REPLACE Package Body EMPPackage
AS
V_sal Number; --Private
Function FullName(p_fname char, p_lname) Return Number --Private
IS
Begin
<Code>
End FullName;
Procedure CalculateBonus(p_deptno Number) --Public
AS
Begin
<Code>
Exception
<Exceptions for this procedure>
End CalculateBonus; -- Cont.. On next slide
Package Body
Procedure UpdateSalary(p_empno Number, p_sal Number) --Public
AS
Begin
<Code>
End UpdateSalary;
Function GetSalary(p_empno Number) Return Number –Public
AS
Begin
<Code>
End GetSalary;

END EMPPack;
Package Body
• Emppack body has:
– One private variable v_sal that can be used only inside this
package.

– Definition of Private Function that can be used only inside


this package.

– Definition of two public procedures CalculateBonus,


UpdateSalary
One public function GetSalary which are declared in
specification.
Use Package
• Public procedures and Functions in Packages
can be used in some other program or can be
used from SQL prompt.

• Calling them is same as we call normal


procedures and functions , only difference is we
need to precede them with the package name.
Use Package
• To call procedure in a package

– In program : In begin section

PackageName.Proc_Name(parameters);

EmpPack.CalculateBonus(10);

– On SQL prompt :
Execute PackageName.Proc_Name(parameters);

Execute EmpPack.CalculateBonus(10);
Use Package
• To call function in a package

– In program : In begin section

Variable := PackageName.Func_Name(parameters);

v_1 := EmpPack. GetSalary(7689);

– On SQL prompt :
Select PackageName.Func_Name(parameters) from dual;

Select EmpPack. GetSalary(7689) from dual;


Package – EmpPack
• From SQL Prompt /SQL Developer:

• Execute EmpPack.UpdateDept(7689,20);

• Select EmpPack.TotalEmpCount(7689) from dual;

Where 7689 is the Empno and 20 is Deptno.


USER_OBJECTS
• This is the view oracle provides you to see what all
packages you have created in your schema.

• Try out :
– Describe USER_OBJECTS;
– select object_type, object_name from
user_objects where object_type = ‘PACKAGE' ;
USER_CODE
• This is the view Oracle provides you to see the code of all package you have
created.

• Try out : Examples


– Describe USER_CODE;
– This will show the code for the package we created
Select * from USER_CODE where NAME = ‘EMPPACK’;
– This will give name of all procedure , functions, packages etc we did so
far:
Select NAME from USER_CODE ;
Deleting package

• Drop Package <Package_Name>;


Thank you !!
Creating Triggers

17-192
Topics To Cover

– Describe database triggers and their uses

6
– Describe the different types of triggers
5
4
3
2 – Create database triggers
1
– Describe database trigger-firing rules

– Remove database triggers

– Display trigger information

17-193
What Are Triggers?
A trigger is a PL/SQL block that is stored in the database
and fired (executed) in response to a specified event.

The Oracle database automatically executes a trigger


when specified conditions occur.

17-194
Defining Triggers

A trigger can be defined on the table, view,


schema (schema owner), or database (all
users).

17-195
Trigger Event Types
You can write triggers that fire whenever one of the
following operations occurs in the database:
– A database manipulation (DML) statement (DELETE,
INSERT, or UPDATE).
– A database definition (DDL) statement (CREATE, ALTER,
or DROP).
– A database operation such as SERVERERROR, LOGON,
LOGOFF, STARTUP, or SHUTDOWN.

17-196
Application and Database Triggers

– Database trigger (covered in this course):


• Fires whenever a DML, a DLL, or system event occurs
on a schema or database
– Application trigger:
• Fires whenever an event occurs within a particular
application

Application Trigger Database Trigger

17-197
Business Application Scenarios
for Implementing Triggers
You can use triggers for:
– Security
– Auditing
– Data integrity
– Referential integrity
– Table replication
– Computing derived data automatically
– Event logging

17-198
Available Trigger Types

Simple DML Non-DML


triggers triggers
•BEFORE •DDL event
triggers
•AFTER
•Database
•INSTEAD
event triggers
OF

17-199
Trigger Event Types and Body

– A trigger event type determines which DML statement


causes the trigger to execute. The possible events are:
• INSERT
• UPDATE [OF column]
• DELETE

– A trigger body determines what action is performed and


is a PL/SQL block or a CALL to a procedure.

17-200
Creating DML Triggers Using the
CREATE TRIGGER Statement
CREATE [OR REPLACE] TRIGGER trigger_name
timing –- when to fire the trigger
event1 [OR event2 OR event3]
ON object_name
[REFERENCING OLD AS old | NEW AS new]
FOR EACH ROW –- default is statement level trigger
WHEN (condition)]]
DECLARE]
BEGIN
... trigger_body –- executable statements
[EXCEPTION . . .]
timing = END [trigger_name];
BEFORE | AFTER | INSTEAD OF

event = INSERT | DELETE | UPDATE | UPDATE OF column_list

17-201
Specifying the Trigger Firing (Timing)

You can specify the trigger timing as to whether to run the


trigger’s action before or after the triggering statement:

– BEFORE: Executes the trigger body before the triggering DML event
on a table.
– AFTER: Execute the trigger body after the triggering DML event on a
table.
– INSTEAD OF: Execute the trigger body instead of the triggering
statement. This is used for views that are not otherwise modifiable.

17-202
Statement-Level Triggers
Versus Row-Level Triggers

Statement-Level Triggers Row-Level Triggers


Is the default when creating a Use the FOR EACH ROW clause
trigger when creating a trigger.
Fires once for the triggering event Fires once for each row affected by
the triggering event
Fires once even if no rows are Does not fire if the triggering event
affected does not affect any rows

17-203
Creating DML Triggers Using SQL Developer

17-204
Trigger-Firing Sequence:
Single-Row Manipulation
Use the following firing sequence for a trigger on a table when
a single row is manipulated:
INSERT INTO departments
(department_id,department_name, location_id)
VALUES (400, 'CONSULTING', 2400);
TRG BEFORE statement trigger

... TRG BEFORE row trigger

TRG AFTER row trigger

TRG AFTER statement trigger

17-205
Trigger-Firing Sequence:
Multirow Manipulation
Use the following firing sequence for a trigger on a table when
many rows are manipulated:
UPDATE employees
SET salary = salary * 1.1
WHERE department_id = 30;
TRG BEFORE statement trigger

BEFORE row trigger


AFTER row trigger
...
BEFORE row trigger
AFTER row trigger
...

TRG AFTER statement trigger

17-206
Creating a DML Statement Trigger Example:
SECURE_EMP

INSERT INTO EMPLOYEES...;

DML statement fires trigger EMPLOYEES table

Application
SECURE_EMP trigger

CREATE OR REPLACE TRIGGER secure_emp


BEFORE INSERT ON employees
BEGIN
IF (TO_CHAR(SYSDATE,'DY') IN ('SAT','SUN')) OR
(TO_CHAR(SYSDATE,'HH24:MI')
NOT BETWEEN '08:00' AND '18:00') THEN
RAISE_APPLICATION_ERROR(-20500, 'You may insert'
||' into EMPLOYEES table only during '
||' normal business hours.');
END IF;
END;
17-207
Testing Trigger SECURE_EMP

INSERT INTO employees (employee_id, last_name,


first_name, email, hire_date, job_id, salary,
department_id)
VALUES (300, 'Smith', 'Rob', 'RSMITH', SYSDATE,
'IT_PROG', 4500, 60);

17-208
Using Conditional Predicates
CREATE OR REPLACE TRIGGER secure_emp BEFORE
INSERT OR UPDATE OR DELETE ON employees
BEGIN
IF (TO_CHAR(SYSDATE,'DY') IN ('SAT','SUN')) OR
(TO_CHAR(SYSDATE,'HH24')
NOT BETWEEN '08' AND '18') THEN
IF DELETING THEN RAISE_APPLICATION_ERROR(
-20502,'You may delete from EMPLOYEES table'||
'only during normal business hours.');
ELSIF INSERTING THEN RAISE_APPLICATION_ERROR(
-20500,'You may insert into EMPLOYEES table'||
'only during normal business hours.');
ELSIF UPDATING ('SALARY') THEN
RAISE_APPLICATION_ERROR(-20503, 'You may '||
'update SALARY only normal during business hours.');
ELSE RAISE_APPLICATION_ERROR(-20504,'You may'||
' update EMPLOYEES table only during'||
' normal business hours.');
END IF;
END IF;
17-209
END;
Creating a DML Row Trigger
CREATE OR REPLACE TRIGGER restrict_salary
BEFORE INSERT OR UPDATE OF salary ON employees
FOR EACH ROW
BEGIN
IF NOT (:NEW.job_id IN ('AD_PRES', 'AD_VP'))
AND :NEW.salary > 15000 THEN
RAISE_APPLICATION_ERROR (-20202,
'Employee cannot earn more than $15,000.');
END IF;
UPDATEEND;
employees
SET salary = 15500
WHERE last_name = 'Russell';

17-210
Using OLD and NEW Qualifiers
– When a row-level trigger fires, the PL/SQL run-time
engine creates and populates two data structures:
• OLD: Stores the original values of the record processed by the
trigger
• NEW: Contains the new values
– NEW and OLD have the same structure as a record
declared using the %ROWTYPE on the table to which the
trigger is attached.
Data Old Value New Value
Operations
INSERT NULL Inserted value
UPDATE Value before update Value after update
DELETE Value before delete NULL

17-211
Using OLD and NEW Qualifiers: Example
CREATE TABLE audit_emp (
user_name VARCHAR2(30),
time_stamp date,
id NUMBER(6),
old_last_name VARCHAR2(25),
new_last_name VARCHAR2(25),
old_title VARCHAR2(10),
new_title VARCHAR2(10),
old_salary NUMBER(8,2),
new_salary NUMBER(8,2) )
/
CREATE OR REPLACE TRIGGER audit_emp_values
AFTER DELETE OR INSERT OR UPDATE ON employees
FOR EACH ROW
BEGIN
INSERT INTO audit_emp(user_name, time_stamp, id,
old_last_name, new_last_name, old_title,
new_title, old_salary, new_salary)
VALUES (USER, SYSDATE, :OLD.employee_id,
:OLD.last_name, :NEW.last_name, :OLD.job_id,
17-212 :NEW.job_id, :OLD.salary, :NEW.salary);
END;
Using OLD and NEW Qualifiers: Example

INSERT INTO employees (employee_id, last_name, job_id,


salary, email, hire_date)
VALUES (999, 'Temp emp', 'SA_REP', 6000, 'TEMPEMP',
TRUNC(SYSDATE))
/
UPDATE employees
SET salary = 7000, last_name = 'Smith'
WHERE employee_id = 999
/
SELECT *
FROM audit_emp;

17-213
Using the WHEN Clause to Fire a
Row Trigger Based on a Condition

CREATE OR REPLACE TRIGGER derive_commission_pct


BEFORE INSERT OR UPDATE OF salary ON employees
FOR EACH ROW
WHEN (NEW.job_id = 'SA_REP')
BEGIN
IF INSERTING THEN
:NEW.commission_pct := 0;
ELSIF :OLD.commission_pct IS NULL THEN
:NEW.commission_pct := 0;
ELSE
:NEW.commission_pct := :OLD.commission_pct+0.05;
END IF;
END;
/
17-214
The Status of a Trigger
A trigger is in either of two distinct modes:
– Enabled: The trigger runs its trigger action if a triggering
statement is issued and the trigger restriction (if any)
evaluates to true (default).
– Disabled: The trigger does not run its trigger action, even
if a triggering statement is issued and the trigger
restriction (if any) would evaluate to true.

17-215
Managing Triggers Using the
ALTER and DROP SQL Statements
-- Disable or reenable a database trigger:

ALTER TRIGGER trigger_name DISABLE | ENABLE;

-- Disable or reenable all triggers for a table:

ALTER TABLE table_name DISABLE | ENABLE ALL TRIGGERS;

-- Recompile a trigger for a table:

ALTER TRIGGER trigger_name COMPILE;

-- Remove a trigger from the database:

DROP TRIGGER trigger_name;

17-216
Managing Triggers Using SQL Developer

17-217
Viewing Trigger Information
You can view the following trigger information:

Data Dictionary View Description


USER_OBJECTS Displays object information
USER/ALL/DBA_TRIGG Displays trigger information
ERS
USER_ERRORS Displays PL/SQL syntax errors for a trigger

17-218
Using USER_TRIGGERS
DESCRIBE user_triggers

SELECT trigger_type, trigger_body


FROM user_triggers
WHERE trigger_name = 'SECURE_EMP';

17-219
THANKS

You might also like