PL_SQL
PL_SQL
1. Introduction to PL/SQL
What is PL/SQL?
PL/SQL Architecture
Anonymous Blocks
4. Cursors in PL/SQL
Implicit Cursors
Explicit Cursors
1/3
Cursor FOR LOOP
Parameterized Cursors
5. Exception Handling
Exception Propagation
7. Triggers in PL/SQL
8. PL/SQL Packages
9. Collections in PL/SQL
2/3
EXECUTE IMMEDIATE Statement
Autonomous Transactions
These topics form a strong foundation for mastering PL/SQL, making it easier to build robust
database applications, automate tasks, and improve performance.
3/3
Oracle SQL Topics Overview
Introduction to PL/SQL
1. What is PL/SQL?
PL/SQL (Procedural Language/Structured Query Language) is Oracle’s procedural extension
of SQL, allowing users to write procedural logic (loops, conditions, error handling) along
with SQL operations.
Key Characteristics
Block-Structured: Code is organized into blocks (DECLARE, BEGIN, EXCEPTION, END).
Procedural Features: Supports loops ( FOR , WHILE ), conditions ( IF-ELSE ), and error
handling ( EXCEPTION ).
Supports SQL: PL/SQL integrates seamlessly with SQL for database operations.
Improves Performance: Reduces multiple calls between SQL and the database, making
execution faster.
DECLARE
v_message VARCHAR2(50) := 'Hello, PL/SQL!';
BEGIN
DBMS_OUTPUT.PUT_LINE(v_message);
END;
/
Output:
sql
Hello, PL/SQL!
1/5
2. Features and Benefits of PL/SQL
2.1. Features
✅ Block-Oriented Execution:
PL/SQL code is grouped into blocks (anonymous or named).
✅ Exception Handling:
Built-in error handling mechanisms using EXCEPTION .
✅ Procedural Constructs:
Supports loops ( FOR , WHILE ), conditions ( IF-ELSE ).
✅ Code Reusability:
Supports stored procedures, functions, and triggers.
✅ Performance Optimization:
Supports bulk processing (BULK COLLECT, FORALL) to handle large data efficiently.
Definition Structured Query Language for data Procedural extension of SQL for
retrieval and manipulation. procedural logic and programming.
Performance Requires multiple queries for logic. Combines logic and SQL, reducing
network traffic.
2/5
Feature SQL PL/SQL
Use Case Retrieving, inserting, updating, and Automating tasks, complex logic, and
deleting data. batch processing.
Example
sql
sql
DECLARE
v_name employees.emp_name%TYPE;
v_salary employees.salary%TYPE;
BEGIN
SELECT emp_name, salary INTO v_name, v_salary FROM employees WHERE department =
'IT' AND ROWNUM = 1;
DBMS_OUTPUT.PUT_LINE('Employee: ' || v_name || ', Salary: ' || v_salary);
END;
/
4. PL/SQL Architecture
PL/SQL follows a three-tier architecture:
3/5
Sends SQL statements to the SQL engine.
Returns data/results.
pgsql
+------------------+ +------------------+
| PL/SQL Block | ----> | PL/SQL Engine |
+------------------+ +------------------+
|
Procedural Statements Executed
|
SQL Statements Sent to
|
+------------------+ +------------------+
| SQL Engine | ----> | Database |
+------------------+ +------------------+
SQL Executed & Data Retrieved
5. Conclusion
PL/SQL is Oracle's procedural extension of SQL used for writing complex logic in blocks.
4/5
PL/SQL architecture ensures optimized execution by handling procedural and SQL
logic separately.
🚀 Next Steps: Want to explore PL/SQL Blocks, Variables, or Exception Handling in depth?
5/5
Oracle SQL Topics Overview
DECLARE
v_message VARCHAR2(50) := 'Hello, PL/SQL!';
BEGIN
DBMS_OUTPUT.PUT_LINE(v_message);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('An error occurred.');
END;
/
Output:
sql
Hello, PL/SQL!
1/8
2. Types of PL/SQL Blocks
2.1. Anonymous Blocks
Do not have a name.
Example:
sql
BEGIN
DBMS_OUTPUT.PUT_LINE('This is an Anonymous Block.');
END;
/
Output:
mathematica
1. Procedures
2. Functions
3. Packages
2/8
Example:
sql
sql
BEGIN
greet_user;
END;
/
Output:
css
2.2.2. Functions
Example:
sql
3/8
To execute the function:
sql
DECLARE
v_msg VARCHAR2(100);
BEGIN
v_msg := get_welcome_message;
DBMS_OUTPUT.PUT_LINE(v_msg);
END;
/
Output:
pgsql
2.2.3. Packages
Example:
sql
sql
4/8
END my_package;
/
sql
BEGIN
my_package.greet;
END;
/
Output:
css
Example:
5/8
sql
DECLARE
v_emp_name employees.emp_name%TYPE; -- Inherits data type of emp_name column
BEGIN
SELECT emp_name INTO v_emp_name FROM employees WHERE employee_id = 101;
DBMS_OUTPUT.PUT_LINE('Employee Name: ' || v_emp_name);
END;
/
Example:
sql
DECLARE
v_emp_record employees%ROWTYPE; -- Stores an entire row from employees table
BEGIN
SELECT * INTO v_emp_record FROM employees WHERE employee_id = 101;
DBMS_OUTPUT.PUT_LINE('Employee: ' || v_emp_record.emp_name || ', Salary: ' ||
v_emp_record.salary);
END;
/
6/8
Example:
sql
DECLARE
c_tax_rate CONSTANT NUMBER := 0.18; -- Constant tax rate
v_total NUMBER := 1000;
BEGIN
DBMS_OUTPUT.PUT_LINE('Tax Amount: ' || (v_total * c_tax_rate));
END;
/
Output:
yaml
Example in SQL*Plus:
sql
BEGIN
DBMS_OUTPUT.PUT_LINE('The salary is: ' || :v_salary);
END;
/
Output:
csharp
7/8
The salary is: 50000
5. Summary
PL/SQL Blocks can be Anonymous (temporary) or Named (Stored procedures,
Functions, Packages).
%TYPE inherits a column’s data type, while %ROWTYPE inherits an entire row
structure.
🚀 Next Steps: Want to learn about PL/SQL Control Structures (IF, LOOPS) or Exception
Handling?
8/8
Oracle SQL Topics Overview
Syntax:
sql
IF condition THEN
-- Statements to execute if condition is true
END IF;
Example:
sql
DECLARE
v_salary NUMBER := 50000;
BEGIN
IF v_salary > 40000 THEN
DBMS_OUTPUT.PUT_LINE('High Salary');
END IF;
1/10
END;
/
Output:
nginx
High Salary
Syntax:
sql
IF condition THEN
-- Statements to execute if condition is true
ELSE
-- Statements to execute if condition is false
END IF;
Example:
sql
DECLARE
v_salary NUMBER := 35000;
BEGIN
IF v_salary > 40000 THEN
DBMS_OUTPUT.PUT_LINE('High Salary');
ELSE
DBMS_OUTPUT.PUT_LINE('Low Salary');
END IF;
END;
/
Output:
2/10
nginx
Low Salary
Syntax:
sql
IF condition1 THEN
-- Execute if condition1 is true
ELSIF condition2 THEN
-- Execute if condition2 is true
ELSIF condition3 THEN
-- Execute if condition3 is true
ELSE
-- Execute if no condition is true
END IF;
Example:
sql
DECLARE
v_marks NUMBER := 85;
BEGIN
IF v_marks >= 90 THEN
DBMS_OUTPUT.PUT_LINE('Grade: A');
ELSIF v_marks >= 80 THEN
DBMS_OUTPUT.PUT_LINE('Grade: B');
ELSIF v_marks >= 70 THEN
DBMS_OUTPUT.PUT_LINE('Grade: C');
ELSE
DBMS_OUTPUT.PUT_LINE('Grade: Fail');
3/10
END IF;
END;
/
Output:
makefile
Grade: B
Syntax:
sql
CASE variable
WHEN value1 THEN statement1
WHEN value2 THEN statement2
ELSE default_statement
END;
Example:
sql
DECLARE
v_dept_no NUMBER := 10;
BEGIN
CASE v_dept_no
WHEN 10 THEN DBMS_OUTPUT.PUT_LINE('HR Department');
WHEN 20 THEN DBMS_OUTPUT.PUT_LINE('Finance Department');
4/10
WHEN 30 THEN DBMS_OUTPUT.PUT_LINE('IT Department');
ELSE DBMS_OUTPUT.PUT_LINE('Unknown Department');
END CASE;
END;
/
Output:
nginx
HR Department
Syntax:
sql
CASE
WHEN condition1 THEN statement1
WHEN condition2 THEN statement2
ELSE default_statement
END;
Example:
sql
DECLARE
v_salary NUMBER := 70000;
BEGIN
CASE
WHEN v_salary > 80000 THEN DBMS_OUTPUT.PUT_LINE('Very High Salary');
WHEN v_salary > 60000 THEN DBMS_OUTPUT.PUT_LINE('High Salary');
ELSE DBMS_OUTPUT.PUT_LINE('Average Salary');
END CASE;
5/10
END;
/
Output:
nginx
High Salary
2. Loops in PL/SQL
Loops are used to execute a block of code multiple times.
Syntax:
sql
LOOP
-- Statements
EXIT WHEN condition;
END LOOP;
Example:
sql
DECLARE
v_counter NUMBER := 1;
BEGIN
LOOP
DBMS_OUTPUT.PUT_LINE('Iteration: ' || v_counter);
v_counter := v_counter + 1;
EXIT WHEN v_counter > 5;
6/10
END LOOP;
END;
/
Output:
makefile
Iteration: 1
Iteration: 2
Iteration: 3
Iteration: 4
Iteration: 5
Syntax:
sql
Example:
sql
DECLARE
v_counter NUMBER := 1;
BEGIN
WHILE v_counter <= 5 LOOP
DBMS_OUTPUT.PUT_LINE('WHILE Loop Iteration: ' || v_counter);
v_counter := v_counter + 1;
END LOOP;
7/10
END;
/
Output:
vbnet
Syntax:
sql
Example:
sql
BEGIN
FOR i IN 1..5 LOOP
DBMS_OUTPUT.PUT_LINE('FOR Loop Iteration: ' || i);
END LOOP;
END;
/
Output:
vbnet
8/10
FOR Loop Iteration: 1
FOR Loop Iteration: 2
FOR Loop Iteration: 3
FOR Loop Iteration: 4
FOR Loop Iteration: 5
Example:
sql
BEGIN
FOR i IN 1..5 LOOP
IF i = 3 THEN
CONTINUE; -- Skip iteration 3
END IF;
DBMS_OUTPUT.PUT_LINE('Iteration: ' || i);
END LOOP;
END;
/
Output:
makefile
Iteration: 1
Iteration: 2
Iteration: 4
Iteration: 5
9/10
Loops can be nested inside each other.
Example:
sql
BEGIN
FOR i IN 1..3 LOOP
FOR j IN 1..2 LOOP
DBMS_OUTPUT.PUT_LINE('Outer Loop: ' || i || ', Inner Loop: ' || j);
END LOOP;
END LOOP;
END;
/
Output:
pgsql
Summary
Conditional Statements: IF-THEN , IF-THEN-ELSE , CASE
🚀 Next Steps: Do you want to learn about PL/SQL Exception Handling or Cursors?
10/10
Oracle SQL Topics Overview
Cursors in PL/SQL
A cursor in PL/SQL is a pointer to a result set of a query. Cursors allow you to fetch and
process rows one at a time.
2. Explicit Cursors – Defined by the user to process multiple rows returned by a query.
1. Implicit Cursors
Automatically created by Oracle for DML statements and SELECT INTO queries.
Attributes:
sql
DECLARE
v_emp_id NUMBER := 101;
1/6
BEGIN
UPDATE employees SET salary = salary + 5000 WHERE employee_id = v_emp_id;
IF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE('Employee salary updated');
ELSE
DBMS_OUTPUT.PUT_LINE('No employee found with ID ' || v_emp_id);
END IF;
2. Explicit Cursors
Used when a SELECT statement returns multiple rows.
sql
DECLARE
CURSOR emp_cursor IS
SELECT employee_id, first_name, salary FROM employees WHERE department_id =
10;
v_emp_id employees.employee_id%TYPE;
v_name employees.first_name%TYPE;
v_salary employees.salary%TYPE;
BEGIN
2/6
OPEN emp_cursor; -- Open the cursor
LOOP
FETCH emp_cursor INTO v_emp_id, v_name, v_salary; -- Fetch row
EXIT WHEN emp_cursor%NOTFOUND; -- Exit loop when no more rows
sql
DECLARE
CURSOR emp_cursor IS
SELECT employee_id, first_name, salary FROM employees WHERE department_id =
10;
BEGIN
FOR emp_rec IN emp_cursor LOOP
DBMS_OUTPUT.PUT_LINE('ID: ' || emp_rec.employee_id || ', Name: ' ||
emp_rec.first_name || ', Salary: ' || emp_rec.salary);
END LOOP;
END;
/
3/6
4. Parameterized Cursors
Cursors that accept parameters to filter data dynamically.
sql
DECLARE
CURSOR emp_cursor(p_dept_id NUMBER) IS
SELECT employee_id, first_name, salary FROM employees WHERE department_id =
p_dept_id;
BEGIN
FOR emp_rec IN emp_cursor(20) LOOP
DBMS_OUTPUT.PUT_LINE('ID: ' || emp_rec.employee_id || ', Name: ' ||
emp_rec.first_name || ', Salary: ' || emp_rec.salary);
END LOOP;
END;
/
sql
4/6
DECLARE
TYPE emp_ref_cursor IS REF CURSOR; -- Define REF CURSOR type
v_emp_cursor emp_ref_cursor; -- Declare cursor variable
v_emp_id employees.employee_id%TYPE;
v_name employees.first_name%TYPE;
v_salary employees.salary%TYPE;
BEGIN
OPEN v_emp_cursor FOR SELECT employee_id, first_name, salary FROM employees
WHERE department_id = 30;
LOOP
FETCH v_emp_cursor INTO v_emp_id, v_name, v_salary;
EXIT WHEN v_emp_cursor%NOTFOUND;
CLOSE v_emp_cursor;
END;
/
Summary
Cursor Type Description Use Case
Explicit Cursor Manually declared for handling multiple rows Fetching multiple
records
REF Cursor Dynamic cursors for handling dynamic SQL Complex queries
5/6
✅ Next Steps: Do you want to learn about PL/SQL Exception Handling or Stored
Procedures & Functions? 🚀
6/6
Oracle SQL Topics Overview
3. Exception Propagation – The way exceptions travel from inner blocks to outer blocks.
1/6
Example: Handling NO_DATA_FOUND and TOO_MANY_ROWS
sql
DECLARE
v_emp_name employees.first_name%TYPE;
BEGIN
-- Selecting a single employee, but it might return no rows or multiple rows
SELECT first_name INTO v_emp_name FROM employees WHERE department_id = 999;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Error: No employee found in this department.');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('Error: Query returned multiple employees. Use a
cursor.');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('An unexpected error occurred.');
END;
/
sql
DECLARE
v_result NUMBER;
BEGIN
v_result := 10 / 0; -- This will cause a division by zero error
EXCEPTION
WHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE('Error: Cannot divide by zero.');
2/6
END;
/
2. User-Defined Exceptions
Sometimes, predefined exceptions are not enough, and we need to define our own custom
exceptions.
sql
DECLARE
v_salary employees.salary%TYPE;
e_low_salary EXCEPTION; -- Declare custom exception
BEGIN
SELECT salary INTO v_salary FROM employees WHERE employee_id = 101;
EXCEPTION
WHEN e_low_salary THEN
DBMS_OUTPUT.PUT_LINE('Error: Salary is below minimum threshold.');
3/6
END;
/
sql
DECLARE
v_salary employees.salary%TYPE;
BEGIN
SELECT salary INTO v_salary FROM employees WHERE employee_id = 102;
END;
/
3. Exception Propagation
If an exception occurs inside a nested block and is not handled there, it is propagated to
the outer block.
4/6
Example: Exception Propagation
sql
DECLARE
v_salary NUMBER;
BEGIN
DECLARE
e_low_salary EXCEPTION;
BEGIN
-- Inner Block
SELECT salary INTO v_salary FROM employees WHERE employee_id = 103;
EXCEPTION
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('Inner Block: Too many employees found.');
-- No handler for e_low_salary here, so it will propagate to the outer block
END;
EXCEPTION
WHEN e_low_salary THEN
DBMS_OUTPUT.PUT_LINE('Outer Block: Salary is too low.');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Outer Block: Unexpected error.');
END;
/
✔ If e_low_salary is raised in the inner block, and it is not handled there, it is passed to
the outer block.
Summary
5/6
Feature Description
User-Defined Exceptions Custom exceptions declared using EXCEPTION and raised using
RAISE .
RAISE_APPLICATION_ERROR Allows defining custom error messages with error codes (-20000 to
-20999).
Exception Propagation If an exception is not handled in the inner block, it moves to the outer
block.
✅ Next Steps: Do you want to learn about Stored Procedures & Functions or Triggers in
PL/SQL? 🚀
6/6
Oracle SQL Topics Overview
1. Procedures in PL/SQL
A Procedure is a stored program that performs a specific task but does not return a value
directly.
1/7
Problem Statement: Create a procedure that increases an employee's
salary by a given percentage.
sql
sql
BEGIN
increase_salary(101, 10); -- Increases salary by 10% for employee 101
END;
/
2/7
2. Functions in PL/SQL
A Function is similar to a procedure but returns a value. It is used when we need a
computed result.
sql
3/7
-- Fetching total salary
SELECT salary INTO v_total_salary
FROM employees
WHERE employee_id = p_emp_id;
RETURN v_total_salary;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL; -- If employee not found, return NULL
END get_total_salary;
/
sql
DECLARE
v_salary NUMBER;
BEGIN
v_salary := get_total_salary(101); -- Fetch salary for employee 101
DBMS_OUTPUT.PUT_LINE('Total Salary: ' || v_salary);
END;
/
✔ A function must always return a value and is used within SELECT , PL/SQL blocks, or
RETURN statements.
4/7
Parameter Mode Description
-- Increase Salary by 5%
p_salary := p_salary * 1.05;
END employee_bonus;
/
sql
DECLARE
v_salary NUMBER := 50000;
v_bonus NUMBER;
BEGIN
employee_bonus(101, v_bonus, v_salary);
5/7
DBMS_OUTPUT.PUT_LINE('Bonus: ' || v_bonus);
DBMS_OUTPUT.PUT_LINE('Updated Salary: ' || v_salary);
END;
/
✔ The salary is modified inside the procedure and reflected in the calling block.
Purpose Performs an action (e.g., insert, update, Computes and returns a value
delete)
Conclusion
✔ Procedures are used when we need to perform an action (e.g., update salaries, insert
records).
✔ Functions are used when we need to compute and return a value (e.g., get total salary).
✔ Parameter modes ( IN , OUT , IN OUT ) allow flexibility in passing values.
6/7
✅ Next Steps: Do you want to cover PL/SQL Triggers or PL/SQL Packages? 🚀
7/7
Oracle SQL Topics Overview
PL/SQL Triggers
What is a Trigger?
A trigger is a PL/SQL program that is automatically executed when a specific event occurs in
the database. It is mainly used to enforce business rules, automate actions, and maintain
data integrity.
INSTEAD OF Trigger Used on views to handle modifications that are not directly possible.
Row-Level Trigger Executes once for each row affected by the DML statement.
Statement-Level Executes once per SQL statement, regardless of how many rows are
Trigger affected.
1/7
Trigger Type Description
Database Event Triggers Fire on system events like LOGON , LOGOFF , STARTUP , SHUTDOWN .
sql
✔ This trigger ensures that every new employee gets a default department_id = 10 if it's not
provided.
sql
2/7
CREATE OR REPLACE TRIGGER after_update_salary
AFTER UPDATE ON employees
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE('Salary updated for Employee ID: ' || :NEW.employee_id);
END;
/
sql
3/7
C. Row-Level vs. Statement-Level Triggers
Row-Level Trigger: Executes once per affected row. ( FOR EACH ROW must be used.)
Statement-Level Trigger: Executes once per SQL statement, regardless of how many
rows are affected.
sql
sql
4/7
DDL triggers are useful for security and auditing purposes.
sql
sql
5/7
What is a Mutating Table Error?
A mutating table error occurs when a trigger tries to read/write from the same table that
triggered it.
sql
✔ This will fail because the employees table is being modified while being queried.
sql
6/7
END;
/
4. Summary of Triggers
Trigger Type Usage
✅ Next Steps: Do you want to cover PL/SQL Packages or any other topic? 🚀
7/7
Oracle SQL Topics Overview
PL/SQL Packages
1. What is a Package in PL/SQL?
A package is a collection of related procedures, functions, variables, cursors, and
exceptions grouped together under a common name. It allows for modular programming,
code reusability, and better performance by pre-compiling the stored procedures.
2. Components of a Package
A package consists of two parts:
1. Package Specification
Acts as a header file that defines procedures, functions, cursors, and variables.
2. Package Body
Can also contain private procedures and variables that are not accessible outside
the package.
1/7
3. Creating a PL/SQL Package
A. Package Specification (Declaration)
sql
-- Public Function
FUNCTION get_employee_salary(p_id NUMBER) RETURN NUMBER;
END emp_package;
/
✔ This declares a procedure and a function but does not implement them.
sql
-- Procedure Implementation
PROCEDURE insert_employee(p_id NUMBER, p_name VARCHAR2, p_salary NUMBER) IS
BEGIN
INSERT INTO employees (employee_id, employee_name, salary)
VALUES (p_id, p_name, p_salary);
COMMIT;
END insert_employee;
-- Function Implementation
FUNCTION get_employee_salary(p_id NUMBER) RETURN NUMBER IS
v_salary NUMBER;
BEGIN
SELECT salary INTO v_salary FROM employees WHERE employee_id = p_id;
RETURN v_salary;
END get_employee_salary;
2/7
END emp_package;
/
✔ The package body contains the actual implementation of the procedures and functions.
4. Using a Package
A. Calling a Procedure from the Package
sql
BEGIN
emp_package.insert_employee(101, 'John Doe', 50000);
END;
/
sql
DECLARE
v_salary NUMBER;
BEGIN
v_salary := emp_package.get_employee_salary(101);
DBMS_OUTPUT.PUT_LINE('Salary: ' || v_salary);
END;
/
✔ This calls the get_employee_salary function to fetch and print an employee's salary.
3/7
🔹 Public vs. Private Procedures
Public Procedures/Functions: Declared in the package specification and can be
accessed outside the package.
sql
END emp_package;
/
4/7
Example: Initializing a Package
sql
sql
5/7
🔹 Stateful vs. Stateless Packages
Stateless: Does not maintain variable values between calls.
sql
-- Increment counter
g_call_count := g_call_count + 1;
END insert_employee;
END emp_package;
/
Public & Private Public procedures are declared in the specification, private procedures are
Procedures defined only in the body.
6/7
Feature Description
Overloading Allows multiple procedures/functions with the same name but different
parameters.
State Management Can maintain state across multiple calls using global variables.
7/7
Oracle SQL Topics Overview
PL/SQL Collections
PL/SQL collections allow us to store and manipulate multiple elements as a single unit,
similar to arrays in other programming languages. Collections improve performance and
simplify handling of large datasets in procedures, functions, and loops.
Associative Arrays (Index-By Key-value pairs, indexed by numbers or strings (like a hash
Tables) table).
VARRAYs (Variable-Size Arrays) Fixed-size array, stored in the database, maintains order.
sql
DECLARE
TYPE emp_table IS TABLE OF VARCHAR2(50) INDEX BY PLS_INTEGER;
employees emp_table;
BEGIN
-- Assign values using index
employees(1) := 'John';
1/6
employees(2) := 'Alice';
employees(3) := 'Bob';
3. Nested Tables
A Nested Table is a collection that can be stored in a database column and modified
dynamically.
sql
DECLARE
TYPE num_table IS TABLE OF NUMBER;
numbers num_table := num_table(10, 20, 30);
BEGIN
-- Extend and add values dynamically
numbers.EXTEND;
numbers(4) := 40;
✔ Nested Tables are flexible, support bulk operations, and can be stored in the database.
2/6
4. VARRAYs (Variable-Size Arrays)
A VARRAY is a fixed-size array stored as a whole in the database.
sql
DECLARE
TYPE emp_varray IS VARRAY(5) OF VARCHAR2(50);
employees emp_varray := emp_varray('John', 'Alice', 'Bob');
BEGIN
-- Access and print values
DBMS_OUTPUT.PUT_LINE('First Employee: ' || employees(1));
DBMS_OUTPUT.PUT_LINE('Last Employee: ' || employees(employees.LAST));
END;
/
✔ VARRAYs are ordered collections and store data as a single object in the database.
Method Description
EXTEND Adds elements dynamically (only for Nested Tables and VARRAYs).
sql
DECLARE
TYPE num_table IS TABLE OF NUMBER;
numbers num_table := num_table(10, 20, 30);
3/6
BEGIN
-- Adding new elements dynamically
numbers.EXTEND;
numbers(4) := 40;
-- Deleting an element
numbers.DELETE(2); -- Deletes second element
sql
DECLARE
TYPE emp_table IS TABLE OF employees%ROWTYPE;
emp_list emp_table;
BEGIN
-- Fetch all employees at once
SELECT * BULK COLLECT INTO emp_list FROM employees;
4/6
END;
/
sql
DECLARE
TYPE num_table IS TABLE OF NUMBER;
emp_ids num_table := num_table(101, 102, 103);
BEGIN
-- Bulk delete operation
FORALL i IN emp_ids.FIRST .. emp_ids.LAST
DELETE FROM employees WHERE employee_id = emp_ids(i);
COMMIT;
END;
/
✔ FORALL reduces the number of context switches, making DML operations 10x faster.
5/6
Feature Associative Arrays Nested Tables VARRAYs
Use Nested Tables for storing dynamic data that needs to be modified frequently.
6/6
Oracle SQL Topics Overview
🔹 Syntax:
sql
1/7
EXECUTE IMMEDIATE 'SQL_STATEMENT';
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE temp_table (id NUMBER, name VARCHAR2(50))';
DBMS_OUTPUT.PUT_LINE('Table Created Successfully');
END;
/
sql
DECLARE
v_emp_name employees.employee_name%TYPE;
v_sql VARCHAR2(200);
BEGIN
-- Construct the query dynamically
v_sql := 'SELECT employee_name FROM employees WHERE employee_id = 101';
2/7
Using USING prevents SQL Injection and improves performance.
sql
DECLARE
v_emp_name employees.employee_name%TYPE;
BEGIN
EXECUTE IMMEDIATE
'SELECT employee_name FROM employees WHERE employee_id = :1'
INTO v_emp_name
USING 101; -- Binding Parameter
sql
BEGIN
-- Dynamic INSERT
EXECUTE IMMEDIATE 'INSERT INTO employees (employee_id, employee_name) VALUES
(105, ''John'')';
-- Dynamic UPDATE
EXECUTE IMMEDIATE 'UPDATE employees SET employee_name = ''Alice'' WHERE
employee_id = 105';
-- Dynamic DELETE
EXECUTE IMMEDIATE 'DELETE FROM employees WHERE employee_id = 105';
COMMIT;
3/7
END;
/
sql
DECLARE
v_cursor NUMBER;
v_sql VARCHAR2(200);
v_emp_name VARCHAR2(100);
v_emp_id NUMBER := 101;
BEGIN
-- Open a cursor for execution
v_cursor := DBMS_SQL.OPEN_CURSOR;
4/7
-- Define the SQL statement
v_sql := 'SELECT employee_name FROM employees WHERE employee_id = :1';
5/7
Feature EXECUTE IMMEDIATE DBMS_SQL
Performance Faster, recommended for most use Slightly slower due to additional
cases parsing
Handling Dynamic Best for known structures with few Useful for completely dynamic
Queries columns queries
6/7
✅ Next Steps: Do you want to explore PL/SQL Records & Composite
Data Types next? 🚀
7/7
Oracle SQL Topics Overview
✅ Use Cases:
Logging information into an audit table without affecting the main transaction.
Committing changes inside a trigger, even if the main transaction rolls back.
sql
1/7
END;
/
✔ This logs an error message in error_log without affecting the main transaction.
2/7
✔ This creates an object type emp_obj with a function get_salary .
DECLARE
emp emp_obj := emp_obj(101, 'John', 50000);
BEGIN
DBMS_OUTPUT.PUT_LINE('Salary: ' || emp.get_salary());
END;
/
✔ Objects help in modeling real-world entities like Employees, Orders, Products, etc.
sql
3/7
SELECT XMLELEMENT("Employee",
XMLFOREST(employee_id AS "ID", employee_name AS "Name")
) AS xml_output
FROM employees;
xml
<Employee>
<ID>101</ID>
<Name>John</Name>
</Employee>
sql
SELECT JSON_OBJECT(
'Employee_ID' VALUE employee_id,
'Employee_Name' VALUE employee_name
) AS json_output
FROM employees;
json
{"Employee_ID":101, "Employee_Name":"John"}
sql
4/7
DECLARE
v_json CLOB := '{"Employee_ID":101, "Employee_Name":"John"}';
v_emp_id NUMBER;
v_emp_name VARCHAR2(100);
BEGIN
SELECT JSON_VALUE(v_json, '$.Employee_ID'),
JSON_VALUE(v_json, '$.Employee_Name')
INTO v_emp_id, v_emp_name
FROM dual;
✅ Use Cases:
Performing complex calculations using Java.
sh
6/7
DECLARE
v_result NUMBER;
BEGIN
v_result := get_square(5);
DBMS_OUTPUT.PUT_LINE('Square: ' || v_result);
END;
/
makefile
Square: 25
🚀 Summary
Feature Use Case Key Benefit
PL/SQL with Object Modeling real-world entities Supports OOP concepts inside
Types PL/SQL
PL/SQL with Working with APIs, data Supports structured and semi-
XML/JSON exchange structured data
Calling Java from Complex computations, external Uses Java's powerful libraries in
PL/SQL API calls PL/SQL
7/7
Oracle SQL Topics Overview
🚀
PL/SQL Performance Tuning and Best
Practices
Performance tuning is essential for optimizing PL/SQL execution speed and reducing
resource consumption. Below are key techniques and best practices for enhancing PL/SQL
performance.
2. Use Bulk Processing – Use BULK COLLECT and FORALL for large data sets.
4. Minimize PL/SQL to SQL Context Switching – Avoid calling SQL statements in loops.
6. Use Proper Data Types – Match PL/SQL and SQL data types to avoid implicit
conversions.
Frequent switching between SQL and PL/SQL (like running a loop for inserts) reduces
performance.
1/6
🔹 Example of Bad Context Switching (Slow Performance)
sql
DECLARE
v_name employees.employee_name%TYPE;
BEGIN
FOR rec IN (SELECT employee_name FROM employees) LOOP
v_name := rec.employee_name;
DBMS_OUTPUT.PUT_LINE(v_name);
END LOOP;
END;
/
DECLARE
TYPE emp_name_tbl IS TABLE OF employees.employee_name%TYPE;
v_names emp_name_tbl;
BEGIN
SELECT employee_name BULK COLLECT INTO v_names FROM employees;
2/6
3. Using BULK COLLECT and FORALL for Performance
🔹 BULK COLLECT – Faster Data Retrieval
✅ How does BULK COLLECT work?
Instead of retrieving one row at a time, BULK COLLECT retrieves all rows at once into a
collection.
sql
DECLARE
TYPE emp_tbl IS TABLE OF employees%ROWTYPE;
v_employees emp_tbl;
BEGIN
SELECT * BULK COLLECT INTO v_employees FROM employees;
DBMS_OUTPUT.PUT_LINE('Total Employees Fetched: ' || v_employees.COUNT);
END;
/
sql
DECLARE
TYPE emp_id_tbl IS TABLE OF employees.employee_id%TYPE;
v_emp_ids emp_id_tbl;
BEGIN
-- Collect all Employee IDs
SELECT employee_id BULK COLLECT INTO v_emp_ids FROM employees WHERE
department_id = 10;
3/6
FORALL i IN v_emp_ids.FIRST .. v_emp_ids.LAST
UPDATE employees SET salary = salary * 1.10 WHERE employee_id =
v_emp_ids(i);
COMMIT;
END;
/
Bitmap Index Useful for columns with low cardinality (e.g., Gender: M/F)
4/6
✔ Improves performance for queries filtering by employee_name .
✔ Useful for queries filtering on few distinct values (e.g., M/F, YES/NO).
Use FORALL for Bulk DML Performs bulk inserts, updates, deletes efficiently
Use Proper Indexing Speeds up queries and reduces full table scans
5/6
Optimization Benefit
Use Bitmap Indexes Best for columns with low distinct values
🚀 Next Steps:
Would you like a hands-on case study demonstrating these optimizations? 🎯
6/6
Oracle SQL Topics Overview
sql
1/6
🔹 Example: Validating Customer Email Format Using PL/SQL
Function
sql
sql
sql
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'JOB_SALARY_UPDATE',
job_type => 'PLSQL_BLOCK',
2/6
job_action => 'BEGIN
UPDATE employees SET salary = salary * 1.05;
COMMIT;
END;',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=MONTHLY; BYMONTHDAY=1',
enabled => TRUE
);
END;
/
sql
3/6
IF v_count = 1 THEN
DBMS_OUTPUT.PUT_LINE('Login Successful');
ELSE
DBMS_OUTPUT.PUT_LINE('Invalid Credentials');
END IF;
END;
/
sql
4/6
🔹 Example: Using PL/SQL to Validate Form Data Before Submission
✔ Scenario: Ensure that Customer Age is at least 18 before submission.
sql
BEGIN
IF :CUSTOMER.AGE < 18 THEN
MESSAGE('Customer must be at least 18 years old.');
RAISE FORM_TRIGGER_FAILURE;
END IF;
END;
/
sql
5/6
🚀 Summary: Real-World Uses of PL/SQL
Use Case PL/SQL Feature Used
🚀 Next Steps:
Would you like a hands-on project demonstrating these PL/SQL real-world applications? 🎯
6/6