Site icon Radu Pârvu

Effective CHECK Constraints for Data Integrity

Welcome back! This is meant to be a detailed article on CHECK constraints and UPDATE behaviour at row level in Oracle SQL, structured for technical readers. The articles main goal being:

Understanding CHECK Constraints During UPDATE Operations in Oracle SQL (Row-Level Validation)

As a reminder, in Oracle Database, data integrity is enforced using constraints such as:

PRIMARY KEY

FOREIGN KEY

CHECK.

Among these, the CHECK constraint plays a crucial role in validating business rules at the row level, especially during INSERT and UPDATE operations.

This article focuses on how CHECK constraints behave during UPDATE statements, how Oracle evaluates them per row, and how to design them effectively.

What is a CHECK Constraint?

A CHECK constraint ensures that a condition is true for every row in a table.

Example:

ALTER TABLE employees
ADD CONSTRAINT chk_salary
CHECK (salary > 0);

This guarantees that no row can have a salary ≤ 0.

How CHECK Constraints Work During UPDATE

When an UPDATE statement is executed:

Row-Level Validation Example
CREATE TABLE employees (
emp_id NUMBER,
salary NUMBER,
bonus NUMBER,
CONSTRAINT chk_compensation CHECK (salary + bonus <= 10000)
);

Make sure we have some data in the table without violating the constraint we added at table creation :)

Next, let us start studying the behaviour during UPDATE

Valid UPDATE
UPDATE employees
SET bonus = 2000
WHERE emp_id = 101;

If salary + bonus <= 10000, the update succeeds:

Invalid UPDATE
UPDATE employees
SET bonus = 9000
WHERE emp_id = 101;

If total exceeds 10000:

ORA-02290: check constraint violated

Important: CHECK Constraints Are Row-Level Only

CHECK constraints:

Supposedly, is not allowed:

CHECK (salary < (SELECT AVG(salary) FROM employees))

This is why CHECK constraints are sometimes confused with more complex validation logic.

NULL Behavior in CHECK Constraints

A key detail:

If a CHECK condition evaluates to NULL, Oracle treats it as valid.

Example:

CHECK (bonus > 0)

If bonus is NULL, the condition becomes:

NULL > 0 → NULL

And the row is accepted!!

In our case, I add a demo constraint:

alter table employees add constraint chk_bonus CHECK (bonus > 1)
;

To be more concrete, I run successfully:

with the end result:

Enforcing stricter logic

To prevent NULL bypass:

CHECK (bonus IS NOT NULL AND bonus >

I will update some new bonus values:

And now, the constraint with both conditions runs fine:

alter table employees add constraint chk_bonus2 CHECK (bonus is not null and bonus > 1);

Column-Level vs Table-Level CHECK Constraints

Column-level, straightforward

salary NUMBER CHECK (salary > 0)
CONSTRAINT chk_total CHECK (salary + bonus <= 10000)

Both behave the same during UPDATE — evaluated per row.

Partial Updates and CHECK Evaluation

Oracle evaluates the constraint using the new row state.

Example:

UPDATE employees
SET salary = 8000
WHERE emp_id = 101;

Even if only salary is updated:

This ensures full row consistency.

To be more precise and to the example, see can see that first update succeeds while resend one will fail:

Deferrable CHECK Constraints

Oracle allows constraints to be deferred until commit:

ALTER TABLE employees
ADD CONSTRAINT chk_salary
CHECK (salary > 0)
DEFERRABLE INITIALLY DEFERRED;

Behavior:

Firstly I can set a salaries to zero :):

but If I try to commit the transaction will roll back:


and we can verify that no salary data has been changed:

Conclusion:

Current Behavior implies that:

CHECK Constraints vs Triggers for UPDATE Validation

FeatureCHECK ConstraintTrigger
Row-level validation
Multi-row logic
Cross-table logic
PerformanceFastSlower
SimplicityHighMore complex

Use:

CHECK Constraints vs Triggers for UPDATE Validation

FeatureCHECK ConstraintTrigger
Row-level validation
Multi-row logic
Cross-table logic
PerformanceFastSlower
SimplicityHighMore complex

Use:

Common Mistakes

1. Ignoring NULL behavior

Leads to unintended valid rows.

2. Trying to enforce cross-row logic

CHECK constraints cannot enforce global rules.

3. Overcomplicated expressions

Keep constraints simple and readable.

Best Practices

Real-World Example: Business Rule Enforcement

ALTER TABLE orders
ADD CONSTRAINT chk_order_amount
CHECK (quantity * price <= 50000);

During UPDATE:

UPDATE orders
SET quantity = 1000
WHERE order_id = 10;

Oracle validates:

quantity * price <= 50000

If violated → update rejected.

Key Takeaways

Conclusion

CHECK constraints in Oracle Database are a powerful mechanism for ensuring data integrity during UPDATE operations. Understanding their row-level behavior, especially with NULL handling and full-row evaluation, is essential for designing reliable database schemas.

Used correctly, they provide a clean, efficient alternative to procedural validation logic.

Next steps to consider when back to your database design work:

Review your existing tables and verify whether your CHECK constraints correctly handle NULL values and UPDATE scenarios.

Thank You!

Also next, I need the help of my readers to tell me which of those topics are great for a technical blog series! Please send me your preferences at: homepage@blog.parvu.org

Exit mobile version