DEV Community

umzzil nng
umzzil nng

Posted on • Originally published at oraerror.com

Oracle ORA-02298 Error: Causes and Solutions Complete Guide

ORA-02298: Cannot Validate – Parent Keys Not Found

ORA-02298 occurs when you try to enable or add a foreign key constraint on a table that already contains rows referencing non-existent parent key values. In short, Oracle refuses to validate the constraint because orphan data — child records with no matching parent — already exists in the table. This error is especially common during data migrations, bulk loads, or when re-enabling previously disabled constraints.


Top 3 Causes

1. Re-enabling a Disabled Foreign Key with Existing Orphan Data

While a constraint was disabled, rows were inserted into the child table without matching parent records. When you attempt ENABLE VALIDATE, Oracle scans all existing rows and immediately raises ORA-02298.

-- Identify orphan records before enabling
SELECT child.order_id, child.customer_id
FROM   orders child
WHERE  NOT EXISTS (
    SELECT 1
    FROM   customers parent
    WHERE  parent.customer_id = child.customer_id
);
Enter fullscreen mode Exit fullscreen mode

2. Wrong Load Order During Data Migration

Child table data was loaded before parent table data, or some parent records were lost during transformation. This is a data quality issue, not just a constraint issue.

-- Insert missing parent records derived from child data
INSERT INTO customers (customer_id, customer_name, created_date)
SELECT DISTINCT o.customer_id, 'MIGRATED_UNKNOWN', SYSDATE
FROM   orders o
WHERE  NOT EXISTS (
    SELECT 1
    FROM   customers c
    WHERE  c.customer_id = o.customer_id
);
COMMIT;
Enter fullscreen mode Exit fullscreen mode

3. Parent Rows Deleted or Updated Without Cascading

Parent records were deleted or updated directly without a CASCADE option configured on the foreign key, leaving child rows pointing to non-existent parents.

-- Check constraint configuration
SELECT constraint_name,
       status,
       validated,
       delete_rule
FROM   user_constraints
WHERE  table_name      = 'ORDERS'
  AND  constraint_type = 'R';
Enter fullscreen mode Exit fullscreen mode

Quick Fix Solutions

Option A – Delete the orphan data (if it's invalid/unnecessary):

DELETE FROM orders
WHERE NOT EXISTS (
    SELECT 1 FROM customers c
    WHERE  c.customer_id = orders.customer_id
);
COMMIT;

ALTER TABLE orders ENABLE VALIDATE CONSTRAINT fk_orders_customers;
Enter fullscreen mode Exit fullscreen mode

Option B – Insert missing parent data (if child data is valid):

INSERT INTO customers (customer_id, customer_name, created_date)
SELECT DISTINCT o.customer_id, 'PLACEHOLDER', SYSDATE
FROM   orders o
WHERE  NOT EXISTS (
    SELECT 1 FROM customers c WHERE c.customer_id = o.customer_id
);
COMMIT;

ALTER TABLE orders ENABLE VALIDATE CONSTRAINT fk_orders_customers;
Enter fullscreen mode Exit fullscreen mode

Option C – Use ENABLE NOVALIDATE (temporary workaround only):

-- Skip validation of existing rows; enforce only for new DML
ALTER TABLE orders ENABLE NOVALIDATE CONSTRAINT fk_orders_customers;
Enter fullscreen mode Exit fullscreen mode

⚠️ NOVALIDATE is a short-term workaround. Always follow up with a full data cleanup and switch to ENABLE VALIDATE.


Prevention Tips

1. Always load parent tables before child tables. Enforce this order in your ETL scripts. If you must disable constraints during a load, re-enable them immediately after with ENABLE VALIDATE as the final step of your batch job.

-- Standard pattern for batch operations
ALTER TABLE orders DISABLE CONSTRAINT fk_orders_customers;
-- ... load data ...
ALTER TABLE orders ENABLE VALIDATE CONSTRAINT fk_orders_customers;
Enter fullscreen mode Exit fullscreen mode

2. Run periodic orphan checks in your monitoring routine. Schedule a regular job to detect NOT VALIDATED constraints and orphan records before they accumulate into a larger problem.

-- Find foreign key constraints not fully validated
SELECT owner, table_name, constraint_name, status, validated
FROM   dba_constraints
WHERE  constraint_type = 'R'
  AND  validated       = 'NOT VALIDATED'
ORDER BY owner, table_name;
Enter fullscreen mode Exit fullscreen mode

Related Oracle Errors

  • ORA-02291 – Raised at DML time when an INSERT or UPDATE references a parent key that does not exist.
  • ORA-02292 – Raised when attempting to DELETE or UPDATE a parent row that still has dependent child rows.
  • ORA-02449 – Raised when dropping a table whose primary/unique key is still referenced by a foreign key in another table.

📖 Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.

Top comments (0)