RDBMS Unit-4
RDBMS Unit-4
PL/SQL AND
TRIGGGERS
Y.A.HATHALIYA
PL/SQL
▪ SQL does not provide procedural capabilities such as conditional
checking, branching and looping, oracle provides PL/SQL(Procedural
Language/Structured Query Language) to overcome the disadvantage of
SQL.
▪ It supports all the facility of SQL along with procedural capabilities.
▪ SQL can be included in PL/SQL program block.
▪ SQL data definition statement such as CREATE is not allowed in PL/SQL.
PL/SQL Advantages
▪ Procedural Capabilities
▪ Support to Variable
▪ Support to OOP
▪ Error Handling Support
▪ Support User Defined Function
▪ Sharing of Code
▪ Portability
▪ Efficient Execution
SQL vs PL/SQL
SQL PL/SQL
Structured Query Language Procedural Language/Structured Query
Language
Mainly used for database manipulation Extend functionality of SQL with
and querying Procedural capabilities.
SQL Statements are executed one at a It is executed as a block which contain
time many SQL statements
Does not provide exception handling Provide exception handling
Does not provide error handling Provide error handling
Not Support OOP Support OOP
Not Support Control Structures Support Control Structures
Not Support Variables Support Variables
Not Support I/O Operations Support I/O Operations
PL/SQL Generic Block Structure
▪ PL/SQL code or a program grouped into structure called a block.
▪ Block can be
• Named block (if some name is given)
• Anonymous block (if no name is given)
▪ PL/SQL block contain three section
1. Declarations Section
2. Executable Command Section
3. Exception Handling Section
▪ Declaration Section
• This section starts with the keyword DECLARE.
• It is an optional section and defines all variables, cursors, subprograms, and
other elements to be used in the program.
▪ Executable Command Section
• This section is enclosed between the keyword BEGIN and END and it is a
mandatory section.
• It consists of the executable PL/SQL statements of the program.
• It should have at least one executable line of code, which may be just a NULL
command to indicate that nothing should be executed.
▪ Exception Handling:
• This section starts with the keyword EXCEPTION.
• This optional section contains exception(s) that handle errors in the program.
# OUTPUT
Hello, World
PL/SQL Datatypes
▪ PL/SQL supports a wide range of data types, enabling developers to store and
manipulate different kinds of data.
▪ Here are some of the commonly used PL/SQL data types:
Data Type Sub Category / Type
Character CHAR
VARCHAR2
VARCHAR
Date DATE
Binary RAW
LONG RAW
Boolean BOOLEAN (Can have TRUE,FALSE,NULL values)
RowID ROWID (Stores value of address location of each record)
Numerical NUMBER
PL/SQL Variables
▪ Variables are declared in the declaration section of the PL/SQL along
with valid datatype.
▪ Some of the basic examples are given below,
v_char CHAR(10) := 'PLSQL’;
v_varchar VARCHAR2(20) := 'Oracle’;
v_num NUMBER(5) := 123;
v_num NUMBER(5,2) := 123.45;
v_date DATE := SYSDATE;
v_flag BOOLEAN := TRUE;
PL/SQL Constants
▪ To declare a constant, you need to use the keyword CONSTANT in the
DECLARE section, followed by the data type and the initial value.
▪ The value must be assigned at the time of declaration and cannot be
changed later.
▪ Syntax:
constant_name CONSTANT data_type := value;
▪ Some of the basic examples are given below,
pi CONSTANT NUMBER := 3.14159;
PL/SQL Displaying Message
▪ In PL/SQL, you can display messages or output to the console using the built-
in package DBMS_OUTPUT.
▪ The procedure DBMS_OUTPUT.PUT_LINE is commonly used to print or
display text messages during the execution of PL/SQL code.
▪ Syntax:
DBMS_OUTPUT.PUT_LINE(message);
▪ Basic examples are given below,
SET SERVEROUTPUT ON; -- Enable output in your SQL environment
BEGIN
DBMS_OUTPUT.PUT_LINE('Hello, welcome to PL/SQL! ');
DBMS_OUTPUT.PUT_LINE('Hello=' || 21);
END;
PL/SQL Comments
▪ In PL/SQL, comments are used to add explanations or notes to your code,
which are ignored by the PL/SQL compiler.
▪ PL/SQL Supports two types of comments,
1. Single-line comments
-- This is a single-line comment
2. Multi-line comments
/* This is a multi-line comment.
It can span multiple lines.
Everything within these symbols is treated as a comment. */
▪ Example: PL/SQL Block for addition of two numbers
DECLARE
num1 NUMBER(3) := 10;
num2 NUMBER(3) := 20;
ans NUMBER(5);
BEGIN
ans:= num1+num2;
DBMS_OUTPUT.PUT_LINE('Addition is:'||ans);
END;
# OUTPUT
30
Anchor Data type
▪ In PL/SQL, the anchor datatype is a feature used to declare variables or
parameters with the same datatype as an existing database column, cursor,
or another variable.
▪ The %TYPE attribute allows you to declare a variable or parameter that has
the same datatype as a specific database column or another variable.
▪ Syntax:
variable_name column_name%TYPE;
▪ Example:
emp_name employees.first_name%TYPE;
-- emp_name will have the same datatype as first_name in
employees table
PL/SQL User Input
▪ In PL/SQL, user input is taken by using following way.
▪ Example:
DECLARE
NO NUMBER(3);
BEGIN
NO:=:NO; or NO:=&NO;
DBMS_OUTPUT.PUT_LINE(NO);
END;
Example: PL/SQL Block for addition of two numbers
DECLARE
num1 NUMBER;
num2 NUMBER;
result NUMBER;
BEGIN
-- Prompt the user to input the first number
num1 := :first_number;
-- Prompt the user to input the second number
num2 := :second_number;
result := num1 + num2;
-- Display the result
DBMS_OUTPUT.PUT_LINE('The sum of ' || num1 || ' and ' || num2 || ' is: ' || result);
END;
# OUTPUT
First Number:10
Second Number:20
The sum of 10 and 20 is: 30
Example: PL/SQL Block with SQL Commands in it.
create table pl1(name varchar2(20),id number(10));
insert into pl1 values(‘yagnik',1);
insert into pl1 values(‘Nipa’,2);
#OUTPUT
The number 7 is Odd
Example: Write a Function to calculate addition of two numbers, also write the
PL/SQL block to invoke/call it.
• Function Creation
CREATE FUNCTION myfunadd (n1 IN NUMBER,n2 IN NUMBER) RETURN NUMBER
IS
n3 NUMBER(8);
BEGIN
n3:= n1+n2;
RETURN n3;
END myfunadd;
#OUTPUT
7 is odd
Example: How to Use Procedure to insert some data to the table, consider
person1 table displayed here
• Procedure Creation
CREATE PROCEDURE myf1(balance IN NUMBER)
IS
BEGIN
insert into person1 values(balance);
END myf1;
#OUTPUT
Statement Processed
Procedure vs Function
Procedure Function
It may or may not return a value It must return a value
Can Return Multiple Values Can Return only one value
Mainly used for performing action Mainly used for computation
Procedure can call a function Function cannot call a procedure
A block of code that performs a task A block of code that performs a task and
without returning a value returns a value
Example: Example:
Exceptions/Exceptions Handling
▪ In PL/SQL, Exceptions are used to handle errors and other exceptional
conditions that arise during execution of PL/SQL Block.
▪ When an error occurs during the execution of a PL/SQL block, an exception is
raised, and control is transferred to the exception-handling part of the block of
PL/SQL which allows the program to respond to the error gracefully instead of
crashing.
▪ Types of Exceptions:
• Predefined/System Defined Exception
• User-defined Exceptions
▪ Basic Syntax for Exception Handling:
DECLARE
-- Declaration
BEGIN
-- Executable statements
EXCEPTION
WHEN exception_name1 THEN
-- Handle the exception
WHEN exception_name2 THEN
-- Handle the exception
……..
……..
……..
WHEN OTHERS THEN
-- Handle all other exceptions
END;
Predefined/System Defined Exceptions
▪ Exception that are automatically raised by the PL/SQL runtime engine when
certain common errors occur is known as predefined exception.
▪ It is a predefined error conditions that oracle database raises in response to
some specific error/exception conditions, you can catch them in your
EXCEPTION block.
▪ These exceptions have pre defined names to identify them.
▪ For example: NO_DATA_FOUND, TOO_MANY_ROWS, ZERO_DIVIDE etc.
▪ It can be further divided into two types,
1. Named Exceptions
2. Unnamed (Numbered) Exceptions
▪ Named Exceptions:
• Named Exceptions are exceptions that are explicitly defined by the Oracle
database and have predefined names, these named exceptions correspond to
certain error codes, which are raised when specific situations occur.
• By using named exceptions, you can write more readable and maintainable
error handling code.
• Here are a few common named exceptions in PL/SQL:
• NO_DATA_FOUND: Raised when a SELECT INTO statement does not return any rows.
• TOO_MANY_ROWS: Raised when a SELECT INTO statement returns more than one
row.
• ZERO_DIVIDE: Raised when an attempt is made to divide a number by zero.
• DUP_VAL_ON_INDEX: Raised when you insert duplicate value in the field where
primary or unique key is declared.
• INVALID_NUMBER: Raised when invalid numeric operation is performed.
• NOT_LOGGED_ON: Raised when you are trying to operation before login.
• LOGON_DENIED: Raised when you are trying to login with wrong user_id/password.
Example of Named Exception:
CREATE TABLE ex1 (id NUMBER(10) PRIMARY KEY, name VARCHAR2(50), salary NUMBER(10));
INSERT INTO ex1 VALUES (1, 'Yagnik', 150000);
INSERT INTO ex1 VALUES (2, 'Nipa', 260000);
DECLARE
l_id NUMBER(10) := 103; -- Non-existing employee ID
l_salary NUMBER(10);
BEGIN
-- Attempt to fetch the salary for an employee who may not exist
SELECT salary INTO l_salary FROM ex1 WHERE id = l_id;
DBMS_OUTPUT.PUT_LINE('Salary: ' || l_salary);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('No employee found with ID ' || l_id);
END;
# OUTPUT: No employee found with ID 103
▪ Unnamed Exceptions:
• Unnamed Exceptions are exceptions that are not predefined by Oracle (like
named exceptions), but are instead handled using the WHEN OTHERS clause
in the EXCEPTION block.
• This allows you to catch any exception that is not specifically handled by a
named exception handler.
• Key Points:
• WHEN OTHERS: This is a catch-all clause that can handle any exception that is
raised and not explicitly caught by other handlers.
• SQLCODE and SQLERRM: These functions allow you to retrieve the error code
and the error message associated with the exception, providing more
information about what went wrong.
Example of Named Exception:
CREATE TABLE ex1 (id NUMBER(10) PRIMARY KEY, name VARCHAR2(50), salary NUMBER(10));
INSERT INTO ex1 VALUES (1, 'Yagnik', 150000);
INSERT INTO ex1 VALUES (2, 'Nipa', 260000);
DECLARE
l_id NUMBER(10) := 1;
l_salary NUMBER(10);
BEGIN
-- Attempting to fetch salary, but introducing an error (division by zero)
SELECT salary / 0 INTO l_salary FROM ex1 WHERE id = l_id;
DBMS_OUTPUT.PUT_LINE('Salary: ' || l_salary);
EXCEPTION
WHEN OTHERS THEN
-- Handling any unexpected exception
DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);
DBMS_OUTPUT.PUT_LINE('Error code: ' || SQLCODE);
END;
# OUTPUT: An error occurred: ORA-01476: divisor is equal to zero
Error code: -1476
User Defined Exceptions
▪ Exceptions that are defined by users are known as User Defined Exceptions.
▪ PL/SQL allows you to define your own exceptions according to the need of your program,
these are explicitly defined by the programmer using the EXCEPTION keyword and raised
using the RAISE statement.
▪ It enhance the code clarity.
▪ Declaring a User-Defined Exception Steps or Sequence:
1. Declare Exception
2. Raise Exception using the RAISE statement
3. Handle Exception it in the EXCEPTION block of PL/SQL
DECLARE
exception_name EXCEPTION; -- Declare the exception
BEGIN
-- Some logic
IF some_condition THEN
RAISE exception_name; -- Raise the exception
END IF;
EXCEPTION
WHEN exception_name THEN
DBMS_OUTPUT.PUT_LINE('User-defined exception occurred.');
END;
Example: We’ll create a table for employees, insert data, and define a custom
exception that will be raised if an employee’s salary is below a certain threshold.
▪ Open a Cursor
• Cursor is opened in executable section of PL/SQL Block.
• When we open cursor:
• Memory is allocated to it for storing data.
• Select statements is executed and associated with cursor.
• Active Data Set is created by retrieving data from table.
• Set the cursor row pointer to point the first record in active data set.
• Syntax: OPEN cursor_name;
▪ Fetch Data From Cursor
• Retrieve each row from the result set.
• The FETCH statement retrieves each row from the cursor into the
declared variables.
FETCH cursor_name INTO variable1,variable2;
▪ Process Data
• Process Retrieved Data.
• Data already fetch in variables which can be processed accordingly.
• Use EXIT WHEN cursor_name%NOTFOUND to stop the loop when all
rows are processed.
▪ Close a Cursor
• Cursor should be closed after processing data, and it will release
the memory associated with the cursor
CLOSE cursor_name;
▪ Syntax to use Explicit Cursor Attribute:
Name_of_Cursor % Attribute_Name
▪ Explicit Cursors Attributes:
Name Use/Impact
SQL%FOUND TRUE if the last fetch returned a row.
FALSE if no row was returned.
SQL%NOTFOUND TRUE if the last fetch did not return a row.
FALSE if a row was returned.
SQL%ROWCOUNT Returns The number of rows fetched so far by the
cursor.
SQL%ISOPEN TRUE if the cursor is open.
FALSE if the cursor is closed.
Example of Explicit Cursor:
CREATE TABLE employees (
employee_id NUMBER(10) PRIMARY KEY,
employee_name VARCHAR2(50),
department_id NUMBER(10),
salary NUMBER(10));
▪ Trigger Disadvantages:
• Increase Overhead of Database
• Difficult to Debug
▪ Types of Trigger:
• Level Trigger
▪ Row Level Trigger
▪ It fires on every record affected by triggering statements.
▪ For example if UPDATE statement updates multiple rows in a table, Row Trigger is
fires once for each row.
▪ It always uses FOR EACH ROW clause in triggering statement.
▪ Statement Trigger
▪ It fires once for each statement.
▪ For example if UPDATE statement updates multiple rows in a table, a statement
trigger is fired only once.
▪ FOR EACH ROW clause not used in triggering statement.
• Timing Trigger
▪ Before Trigger
▪ It fires before triggering statements (before the execution of DML statements)
▪ After Trigger
▪ It fires after triggering statements (after the execution of DML statements)
▪ Trigger Syntax:
CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER }
{INSERT | UPDATE | DELETE}
ON table_name
[FOR EACH ROW]
DECLARE
--declarations
BEGIN
--executable
EXCEPTION
--exceptions
END;
▪ Syntax to DROP a Trigger is:
DROP TRIGGER trigger_name;
Example:
Step:1 Create Tables
CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
Name VARCHAR(50),
Salary DECIMAL(10, 2));
Step:2 Create the Trigger (This trigger will print a message whenever a new
employee is inserted with a salary lower than 20000)
CREATE OR REPLACE TRIGGER MinSalaryTrigger
BEFORE INSERT ON Employees
FOR EACH ROW
BEGIN
IF :NEW.Salary < 20000 THEN
dbms_output.put_line('please enter a valid salary');
END IF;
END;
Step:3 Insert data and see the trigger in action
-- Insert an employee with a lower salary
INSERT INTO Employees VALUES (1, 'Amit', 15000);
#OUTPUT: please enter a valid salary
Step:3 Use the Package (Retrieving Employee Salary Using the Package Function)
DECLARE
v_salary NUMBER;
BEGIN
v_salary := employee_pkg.get_employee_salary(1);
DBMS_OUTPUT.PUT_LINE('Salary of employee 1 is: ' || v_salary);
END;