Oracle PL/SQL Essentials Guide
Oracle PL/SQL Essentials Guide
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