Skip to main content

SQL ON DELETE RESTRICT: Prevent Accidental Data Loss

Understand how SQL ON DELETE RESTRICT protects data integrity. Learn how it blocks unsafe deletes and when to choose it over CASCADE or SET NULL rules.
Jan 16, 2026  · 10 min read

Deleting data in SQL is usually not as simple as removing a single row. In relational databases, tables are often connected, and deleting a record in one can have an impact on another table. 

SQL provides the ON DELETE clause, which defines what should happen when a referenced row is deleted. After the ON DELETE clause, you can specify what happens, such as blocking the delete, automatically removing the dependent row, or updating the referenced data.

In this tutorial, I will show you the ON DELETE RESTRICT constraint, which prevents the deletion of a parent row if any dependent child rows still exist. I will also cover extensively how the constraint works, why databases enforce it, and when it’s the right choice compared to other delete rules. Finally, if you’re looking for the opposite behavior — where deleting a parent row automatically removes related records — see our guide on SQL ON DELETE CASCADE.

What Is ON DELETE RESTRICT in SQL?

The ON DELETE RESTRICT constraint in SQL is a database safety feature. It ensures that you cannot delete a "parent" record if there are "child" records still pointing to it.

Note: While databases like PostgreSQL and MySQL support the RESTRICT keyword directly, SQL Server enforces the same restriction behavior using ON DELETE NO ACTION instead.

Referential integrity and foreign keys

Referential integrity is the principle that relationships between tables must remain valid at all times. Foreign keys enforce this by requiring that values in a child table correspond to existing rows in a parent table. For example, a DepartmentID in the Employees table might reference a specific ID in the Departments table.

Therefore, SQL DELETE rules exist because removing a parent row can break this relationship. The database needs clear instructions on whether to block the delete, cascade it, or apply another action to dependent rows.

What RESTRICT actually means

When you define a foreign key with ON DELETE RESTRICT, the database checks for related child rows before executing a delete. If a child record exists, the delete operation is rejected automatically.  In this case, RESTRICT stops the deletion from happening rather than modifying the data, as we will see later in the tutorial.

How ON DELETE RESTRICT Works in SQL

To understand how the ON DELETE RESTRICT constraint works, you need to see how the database evaluates deletes step by step during a transaction.

Parent and child table relationships

In SQL, the parent table holds the primary records, while the child table holds the dependent records. For example, your database may have a parent table Categories with a category_id of “Electronics.” The child table Products will have a record “Smartphone”, then linked to the parent table using the category_id.

When you run a DELETE command on the parent table, the database engine immediately scans all associated child tables to see if any rows are pointing to that specific parent ID.

What happens when you try to delete restricted rows?

If you attempt to delete a parent row that is still referenced, the database stops the operation and raises an error. This error message indicates a violation of a foreign key constraint.

This behavior is intentional, forcing you to make a conscious decision to either delete or update the dependent child rows first, or reconsider whether the parent row should be removed at all.

The SQL ON DELETE RESTRICT vs. Other Delete Rules

In a DBMS, there are specific rules that govern how data can be deleted from related tables. In this section, we will compare the ON DELETE RESTRICT constraint with the common delete rules in SQL, so you can clearly see how each one affects related data.

RESTRICT vs. CASCADE in SQL

The SQL RESTRICT constraint blocks parent row deletion if child rows reference it, ensuring no accidental data loss. The following query shows how to implement RESTRICT when defining the table schema. It prevents deleting a customer if there are any orders that reference that customer.

-- Parent table
CREATE TABLE customers (
    customer_id INT PRIMARY KEY,
    name VARCHAR(100)
);

-- Child table with ON DELETE RESTRICT
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    CONSTRAINT fk_orders_customers
        FOREIGN KEY (customer_id)
        REFERENCES customers(customer_id)
        ON DELETE RESTRICT
);

However, the SQL CASCADE constraint ensures that a deletion automatically deletes all dependent child rows. In the example below, CASCADE allows the automatic deletion of all orders associated with a customer when the customer record is deleted.

-- Child table with ON DELETE CASCADE
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    CONSTRAINT fk_orders_customers
        FOREIGN KEY (customer_id)
        REFERENCES customers(customer_id)
        ON DELETE CASCADE
);

RESTRICT vs. SET NULL and SET DEFAULT

The SQL SET NULL and SET DEFAULT constraints preserve child rows but change how they reference the parent.

For example, in the query below, when a customer is deleted, the customer_id in related orders is set to NULL, keeping the order records but removing the link to the customer.

-- Child table using SET NULL
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT NULL,
    CONSTRAINT fk_orders_customers
        FOREIGN KEY (customer_id)
        REFERENCES customers(customer_id)
        ON DELETE SET NULL
);

If you use the SET DEFAULT constraint, when a customer is deleted, the customer_id in related orders is set to its default value, preserving the order records while assigning them a predefined placeholder value.

-- Child table using SET DEFAULT
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT DEFAULT 0,
    CONSTRAINT fk_orders_customers
        FOREIGN KEY (customer_id)
        REFERENCES customers(customer_id)
        ON DELETE SET DEFAULT
);

Creating Foreign Keys with ON DELETE RESTRICT in SQL

To implement the ON DELETE RESTRICT constraint in SQL, you need to define it when you create the relationship between two tables.

Defining RESTRICT in table schemas

You can specify the delete behavior in SQL when creating the table or add it afterwards if your table already exists.

The example below shows how to use the SQL ON DELETE RESTRICT foreign key constraint in the CREATE TABLE statement when defining a new table in SQL.

-- Stores department details
CREATE TABLE departments (
    department_id INT PRIMARY KEY, 
    department_name VARCHAR(100)
);

-- -- Prevents deleting a department with employees
CREATE TABLE employees (
    employee_id INT PRIMARY KEY,      -- Unique employee identifier
    department_id INT, 
    CONSTRAINT fk_employees_departments
        FOREIGN KEY (department_id)
        REFERENCES departments(department_id)
        ON DELETE RESTRICT 
);

The query below adds the same foreign key rule to an existing employees table in the SQL ALTER TABLE statement, to prevent the deletion of departments that are still referenced by employees.

-- Adds a foreign key constraint after the table already exists
ALTER TABLE employees
ADD CONSTRAINT fk_employees_departments
FOREIGN KEY (department_id)
REFERENCES departments(department_id)
ON DELETE RESTRICT;    -- Blocks deletion of departments that have employees

Default delete behavior in SQL

In many popular database systems, such as SQL Server, PostgreSQL, and MySQL, RESTRICT is the default behavior. If you define a foreign key without specifying any ON DELETE clause, the database will usually act as if you wrote ON DELETE NO ACTION or ON DELETE RESTRICT. This database engine design ensures you receive an error rather than accidentally delete large amounts of related data.

Common Use Cases for ON DELETE RESTRICT in SQL

In real-world scenarios, the SQL ON DELETE RESTRICT constraint is applied where data integrity demands explicit oversight before deletions.

Protecting critical reference data

The SQL RESTRICT constraint is commonly used for tables that represent core reference data, such as users, accounts, products, or lookup values. These records are often shared across multiple parts of the system, and deleting them automatically could result in widespread data loss or inconsistencies.

For example, deleting a user who still owns orders, audit logs, or permissions is usually unsafe. With the SQL ON DELETE RESTRICT constraint, the database blocks the delete and forces you to resolve those dependencies first, preserving the integrity of historical and transactional data.

Enforcing explicit cleanup workflows

The SQL RESTRICT constraint is also useful when you want cleanup to be intentional and traceable. It forces developers and administrators to be deliberate about how they handle data. Instead of letting the database automatically delete records, the RESTRICT constraint forces you to review the dependent data to decide whether to delete the child records, reassign them to a new parent, or cancel the operation.

Troubleshooting DELETE Errors Caused by RESTRICT in SQL

When the ON DELETE RESTRICT constraint blocks a delete, the resulting error can be confusing if you’re not expecting it. Understanding these errors helps you resolve them safely.

Understanding constraint violation errors

When you attempt to delete a parent row that is still referenced, the database raises a foreign key constraint violation. The following is how the message will appear in different database systems:

  • PostgreSQL: ERROR: update or delete on table "parent_table" violates foreign key constraint "fk_name" on table "child_table"

  • MySQL: Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails…

  • SQL Server: The DELETE statement conflicted with the REFERENCE constraint "FK_Name". The conflict occurred in database "DBName", table "dbo.ChildTable", column 'ParentID'.

In all the databases, the error message will indicate the following:

  • Which foreign key constraint was violated
  • Which table is acting as the child
  • Which key value is still being referenced

Safely resolving blocked deletes

If you get the error message of a blocked delete, but you wanted to delete the parent row, I recommend using any of the following options:

Delete the child record first: If the dependent data is no longer needed, run a DELETE statement on the child rows first, then delete the parent record.

-- Step 1: Remove dependencies
DELETE FROM Orders WHERE CustomerID = 501; 
-- Step 2: Now the parent delete will work
DELETE FROM Customers WHERE CustomerID = 501;

Update child references: If you want to retain the child rows but remove the parent, update the child rows to reference a different parent ID.

-- Reassign orders to a "General" customer account (ID 999)
UPDATE Orders SET CustomerID = 999 WHERE CustomerID = 501;

Change the constraint: In rare administrative scenarios, you may temporarily disable foreign key checks. This is a risky operation that can lead to data corruption if not handled with extreme care.

Database-Specific Notes and Behavior

While the concept of the ON DELETE RESTRICT constraint in SQL is standard across SQL databases, different engines handle the timing and internal logic slightly differently.

PostgreSQL, MySQL, and SQL Server behavior

In PostgreSQL, MySQL, and SQL Server, the ON DELETE RESTRICT constraint prevents deleting a parent row when related child rows exist. However, these engines have the following minor syntax differences:

MySQL: Strictly follows the SQL RESTRICT constraints. If you don't specify a rule, it defaults to RESTRICT.

-- MySQL: RESTRICT is the default if no rule is specified
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    FOREIGN KEY (customer_id)
        REFERENCES customers(customer_id)
);

PostgreSQL: Supports both RESTRICT and NO ACTION constraints. While they behave almost identically, RESTRICT is strictly immediate, whereas NO ACTION allows for deferred checks.

-- PostgreSQL: NO ACTION (can be deferred)
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    FOREIGN KEY (customer_id)
        REFERENCES customers(customer_id)
        ON DELETE NO ACTION
);

SQL Server: Uses NO ACTION constraint as its equivalent to the standard RESTRICT behavior. It does not explicitly use the keyword RESTRICT in its T-SQL syntax, but achieves the same result by preventing the delete.

-- SQL Server: Uses NO ACTION instead of RESTRICT
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    CONSTRAINT fk_orders_customers
        FOREIGN KEY (customer_id)
        REFERENCES customers(customer_id)
        ON DELETE NO ACTION
);

I recommend taking our Introduction to SQL Server and Creating PostgreSQL Databases courses to learn more about the differences in the SQL dialects when creating databases.

Deferred constraints and transaction behavior

In advanced database configurations, such as in PostgreSQL or Oracle, you may encounter deferred constraints. This means that the constraint is checked at transaction commit time, rather than immediately when the DELETE statement is executed.

In such systems, a delete that would normally be blocked by RESTRICT may appear to succeed temporarily within a transaction, only to fail when you attempt to commit. This allows for complex, multi-step operations, such as deleting and reinserting related data within the same transaction, while still enforcing integrity at the end.

Our Introduction to Oracle SQL course will help you further understand how Oracle processes queries.

Choosing the Right ON DELETE Strategy

Selecting the correct constraint helps you strike a balance between data integrity and application usability. Consider the following scenarios to help you choose the appropriate method with the ON DELETE clause.

When RESTRICT is the safest choice

Use the SQL ON DELETE RESTRICT constraint when:

  • The data is highly valuable: The parent records are important and widely referenced in the database.

  • Manual review is required: You want to force a human or a specific business logic flow to decide what happens to dependent data.

  • Preventing “Silent” deletions: You want to ensure that a developer doesn't accidentally wipe out thousands of rows with a single CASCADE delete.

I suggest you try out the SQL Server for Database Administrators skill track if you regularly design or maintain databases as part of your work. 

When to consider alternatives

Where the RESTRICT constraint might be too rigid for your system, consider the following options:

  • Use the CASCADE constraint when the child record has no meaning without the parent record.

  • Use the SET NULL constraint when the relationship is optional.

  • Use the SET DEFAULT vconstraint when you have a “placeholder” that should inherit all orphaned records to keep the system running smoothly.

Conclusion

The SQL ON DELETE RESTRICT constraint is a protective foreign key rule that prioritizes data integrity over convenience by blocking the deletion of parent rows when dependent child records still exist. By encouraging deliberate cleanup strategies and clear ownership of delete operations, SQL RESTRICT constraint acts as a safety feature in relational design. As a best practice, always choose SQL delete rules based on business logic and data semantics, rather than defaulting to convenience or short-term needs.

I recommend taking our Database Design course, where you will learn to create and manage databases and select the appropriate DBMS for your needs. I also recommend trying out our Associate Data Engineer in SQL career track to learn the fundamentals of data engineering and data warehousing.  


Allan Ouko's photo
Author
Allan Ouko
LinkedIn
I create articles that simplify data science and analytics, making them easy to understand and accessible.

SQL ON DELETE RESTRICT FAQs

What’s the difference between RESTRICT and NO ACTION?

In most databases, they behave the same. RESTRICT checks immediately, while NO ACTION may be checked at statement or transaction end.

What happens when I try to delete a restricted parent row?

The DELETE operation fails, and the database raises a foreign key constraint violation error.

How is ON DELETE RESTRICT different from ON DELETE CASCADE?

RESTRICT blocks the delete entirely, while CASCADE automatically deletes all dependent child rows.

How do I resolve a DELETE blocked by ON DELETE RESTRICT?

How do I resolve a DELETE blocked by ON DELETE RESTRICT?

Can I change an existing foreign key to use ON DELETE RESTRICT?

Yes. You can drop and recreate the foreign key constraint with ON DELETE RESTRICT using ALTER TABLE.

Topics

Learn SQL with DataCamp

Course

Introduction to Relational Databases in SQL

4 hr
181.6K
Learn how to create one of the most efficient ways of storing data - relational databases!
See DetailsRight Arrow
Start Course
See MoreRight Arrow
Related

Tutorial

SQL ON DELETE CASCADE: Automatically Remove Dependent Data

Understand how SQL ON DELETE CASCADE automates dependent deletes in SQL, keeps tables consistent, and helps prevent accidental data loss.
Allan Ouko's photo

Allan Ouko

Tutorial

SQL Foreign Key: Keep Your Database Relationships in Check

Find out how foreign keys tie tables together, stop invalid data from slipping in, and help your database stay consistent.
Allan Ouko's photo

Allan Ouko

Tutorial

Integrity Constraints in SQL: A Guide With Examples

Integrity constraints in SQL are rules enforced on database tables to maintain data accuracy, consistency, and validity, such as ensuring unique primary keys and valid foreign key relationships.
François Aubry's photo

François Aubry

Tutorial

SQL Injection: How it Works and How to Prevent it

Learn about SQL injection, how it works, and how to protect your system from malicious attacks.
Marie Fayard's photo

Marie Fayard

Tutorial

Cleaning Data in SQL

In this tutorial, you'll learn techniques on how to clean messy data in SQL, a must-have skill for any data scientist.
Sayak Paul's photo

Sayak Paul

Tutorial

SQL Triggers: A Guide for Developers

Learn how to use SQL triggers to automate tasks, maintain data integrity, and enhance database performance. Try practical examples like the CREATE, ALTER, and DROP commands in MySQL and Oracle.
Oluseye Jeremiah's photo

Oluseye Jeremiah

See MoreSee More