Ошибка ORA-02291: integrity constraint violated - parent key not found
- Запросы
INSERTилиUPDATEзавершаются с ошибкойORA-02291: integrity constraint (SCHEMA.FK_NAME) violated - parent key not found. - Вставка дочерней записи ссылается на несуществующий первичный или уникальный ключ в родительской таблице.
- Сбои в ETL-процессах и синхронизации данных между базами.
1. Определение таблицы и полей внешнего ключа
SELECT a.table_name AS child_table,
a.constraint_name AS fk_name,
c_pk.table_name AS parent_table,
b.column_name AS fk_column
FROM all_constraints a
JOIN all_cons_columns b ON a.constraint_name = b.constraint_name
JOIN all_constraints c_pk ON a.r_constraint_name = c_pk.constraint_name
WHERE a.constraint_name = 'FK_NAME' AND a.owner = 'SCHEMA_NAME';2. Поиск отсутствующих родительских значений
SELECT DISTINCT child.fk_column
FROM child_table child
LEFT JOIN parent_table parent ON child.fk_column = parent.pk_column
WHERE parent.pk_column IS NULL;3. Временное отключение ограничения для массовой загрузки (Осторожно)
ALTER TABLE child_table DISABLE CONSTRAINT fk_name;
-- Выполнение загрузки родительских и дочерних данных...
-- Включение с проверкой целостности
ALTER TABLE child_table ENABLE CONSTRAINT fk_name;4. Включение ограничения в режиме NOVALIDATE
Если в таблице уже есть исторические некорректные данные, но новые нужно валидировать:
ALTER TABLE child_table ENABLE NOVALIDATE CONSTRAINT fk_name; Частые вопросы (FAQ)
Почему возникает ORA-02291?
Значение, вставляемое в столбец с Foreign Key, отсутствует в родительской таблице (в столбце Primary Key или Unique Constraint), что нарушает реляционную целостность.
Как найти имя ограничения, если текст ошибки обрезан?
Запросите ALL_CONSTRAINTS по маске constraint_name из текста системного исключения.
Может ли значение NULL в столбце Foreign Key вызвать ORA-02291?
Нет, значение NULL в столбце внешнего ключа допускается стандартом SQL и не проверяется по родительской таблице (если на столбце нет ограничения NOT NULL).
Что такое DEFERRABLE Foreign Key?
Это ограничение, проверка которого может быть отложена до момента выполнения COMMIT (SET CONSTRAINTS ALL DEFERRED), позволяя вставлять дочерние строки раньше родительских внутри одной транзакции.