Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • Databases
  • SQL
  • MySQL
  • PostgreSQL
  • PL/SQL
  • MongoDB
  • SQL Cheat Sheet
  • SQL Interview Questions
  • MySQL Interview Questions
  • PL/SQL Interview Questions
  • Learn SQL and Database
Open In App
Next Article:
Join Multiple Tables Using Inner Join
Next article icon

Fixing Mutating Table Error in PL/SQL

Last Updated : 11 Oct, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

In PL/SQL, the mutating table error occurs when a trigger tries to modify a table that is already being modified by the statement that caused the trigger to fire. This restriction ensures data consistency by preventing a row-level trigger from querying or modifying the same table.

To avoid this error, developers can use strategies like compound triggers, using statement-level triggers instead of row-level, or utilizing temporary tables to hold data. This article explains why the mutating table error occurs in PL/SQL and provides various strategies to fix it.

What is the Mutating Table Error?

A mutating table error occurs when a row-level trigger tries to access the same table which causes the trigger to fire. This causes Oracle to throw the error ORA-04091: table <table_name> is mutating, trigger/function may not see it. The error arises because PL/SQL prevents the table from being queried to maintain data consistency.

Example of the Mutating Table Error

Consider the following scenario where we try to create a trigger to update the salary of an employee based on a change in their department:

Query:

CREATE TABLE employees (
employee_id NUMBER PRIMARY KEY,
department_id NUMBER,
salary NUMBER
);

INSERT INTO employees VALUES (1, 101, 5000);
INSERT INTO employees VALUES (2, 102, 6000);

-- Creating a trigger to update salary if department changes
CREATE OR REPLACE TRIGGER update_salary
BEFORE UPDATE ON employees
FOR EACH ROW
BEGIN
IF :NEW.department_id != :OLD.department_id THEN
UPDATE employees
SET salary = salary + 500
WHERE employee_id = :NEW.employee_id;
END IF;
END;
/

-- Trying to update the department, which should trigger the salary update
UPDATE employees
SET department_id = 103
WHERE employee_id = 1;

Output:

ORA-04091: table EMPLOYEES is mutating, trigger/function may not see it

Explanation:

Here, we get a mutating table error because the trigger is trying to modify the employees table while the UPDATE statement is already in progress.

Fixing the Mutating Table Error

Fixing the mutating table error involves using various strategies to ensure data consistency and prevent triggers from modifying the same table during execution. Approaches include using compound triggers, implementing statement-level triggers, or using temporary tables to hold data outside of the trigger's immediate scope

1. Using a Statement-Level Trigger

A statement-level trigger fires once for the entire DML operation rather than once for each row. This avoids the mutating table issue since it does not act on individual rows while the update is still in progress.

Query:

CREATE OR REPLACE TRIGGER update_salary_stmt
BEFORE UPDATE ON employees
BEGIN
IF UPDATING('department_id') THEN
UPDATE employees
SET salary = salary + 500
WHERE department_id != :OLD.department_id;
END IF;
END;
/

-- Now, running the same update query
UPDATE employees
SET department_id = 103
WHERE employee_id = 1;

Output:

1 row updated

Explanation:

In this case, the update successfully modifies the department_id of the specified employee and adjusts the salaries of others without causing a conflict, as the condition prevents the trigger from directly altering the row that triggered it. This approach avoids the mutating table error but may not offer the fine-grained control.

2. Using an Autonomous Transaction

By using an autonomous transaction, we can perform the required operations in a separate transaction that is independent of the main transaction. This prevents the mutating table error.

Query:

CREATE OR REPLACE TRIGGER update_salary_autonomous
BEFORE UPDATE ON employees
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF :NEW.department_id != :OLD.department_id THEN
UPDATE employees
SET salary = salary + 500
WHERE employee_id = :NEW.employee_id;
COMMIT;
END IF;
END;
/

Output:

1 row updated

Explanation:

Using an autonomous transaction avoids the mutating error by allowing the trigger to update the table independently. By committing within the trigger, it safely adjusts the employee's salary without conflicting with the ongoing update of the department_id, leading to a successful update of the row.

3. Using a Compound Trigger

A compound trigger can help avoid the mutating table error by providing a way to collect changes across row-level events and process them in the AFTER STATEMENT section of the trigger.

Query:

CREATE OR REPLACE TRIGGER update_salary_compound
FOR UPDATE ON employees
COMPOUND TRIGGER
TYPE emp_list IS TABLE OF employees%ROWTYPE INDEX BY PLS_INTEGER;
employees_to_update emp_list;

BEFORE EACH ROW IS
BEGIN
IF :NEW.department_id != :OLD.department_id THEN
employees_to_update(employees_to_update.COUNT + 1).employee_id := :NEW.employee_id;
END IF;
END BEFORE EACH ROW;

AFTER STATEMENT IS
BEGIN
FOR i IN 1..employees_to_update.COUNT LOOP
UPDATE employees
SET salary = salary + 500
WHERE employee_id = employees_to_update(i).employee_id;
END LOOP;
END AFTER STATEMENT;
END;
/

Output:

1 row updated

Explanation:

In this approach, the compound trigger gathers employee IDs in a list during the BEFORE EACH ROW phase and then makes the updates in the AFTER STATEMENT phase, once the table is no longer being changed.

Conclusion

The mutating table error in PL/SQL happens when a row-level trigger tries to query or update the same table that is being modified. To fix this, we can use statement-level triggers, autonomous transactions, or compound triggers. These methods let us keep the desired functionality without triggering the error.


Next Article
Join Multiple Tables Using Inner Join

A

abhay94517
Improve
Article Tags :
  • Databases
  • PL/SQL

Similar Reads

  • Decision Making in PL/SQL
    PL/SQL (Procedural Language/Structured Query Language) is Oracle's extension to SQL that allows for procedural programming within databases. It features various conditional statements to control the flow of execution based on specific conditions. In this article, We will learn about the various PL/S
    5 min read
  • PL/SQL SELECT INTO Existing Table
    PL/SQL is a programming language that is used alongside SQL for writing procedural code such as stored procedures, functions, triggers, and packages within the Oracle Database. It was developed by Oracle Corporation and is widely used in database programming. PL/SQL is a programming language that ha
    5 min read
  • Joining 4 Tables in SQL
    The purpose of this article is to make a simple program to Join two tables using Join and Where clause in SQL. Below is the implementation for the same using MySQL. The prerequisites of this topic are MySQL and the installment of Apache Server on your computer. Introduction :In SQL, a query is a req
    3 min read
  • How to Pagination in PL/SQL?
    Pagination is a technique used to divide large datasets into smaller, manageable chunks called pages. It's important for improving user experience and optimizing database performance. In PL/SQL, pagination can be achieved using various methods, allowing users to navigate through query results effici
    5 min read
  • Join Multiple Tables Using Inner Join
    To retrieve data from the single table we use SELECT and PROJECTION operations but to retrieve data from multiple tables we use JOINS in SQL. There are different types of JOINS in SQL. In this article, only operations on inner joins in MSSQL are discussed. Inner Join is the method of retrieval of da
    3 min read
  • How to Count Distinct Values in PL/SQL?
    PL/SQL, an extension of SQL for Oracle databases, allows developers to blend procedural constructs like conditions and loops with the power of SQL. It supports exception handling for runtime errors and enables the declaration of variables, constants, procedures, functions, packages, triggers, and mo
    6 min read
  • How to Retrieve Data from Multiple Tables in PL/SQL
    PL/SQL is “Procedural Language extensions to the Structured Query Language”. SQL is a popular language for both querying and updating data in relational database management systems (RDBMS). PL/SQL adds many procedural constructs to SQL language to overcome some limitations of SQL. In addition, PL/SQ
    5 min read
  • PL/SQL Derived Tables
    Derived Tables in PL/SQL are temporary result sets that are created within the execution of a SQL statement. These are essential tools that allow developers to create temporary result sets within SQL statements. This feature enables complex queries to be simplified and enhances readability by encaps
    4 min read
  • How to Compute a Moving Average in PL/SQL?
    A moving average is a technique we use to analyze and determine some specific trends in our provided data. Through moving averages, we can analyze and determine trends in our data along with some other benefits like noise reduction in our data. In this article, we are going to learn about "how to co
    5 min read
  • PL/SQL Nested Table
    PL/SQL, Oracle's procedural extension of SQL, offers powerful capabilities for managing and processing data within the database. One of its key features is support for complex data structures, including collections like nested tables. A nested table in PL/SQL is a dynamic, array-like data structure
    5 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences