Oracle ORA-02292 오류 원인과 해결 방법 완벽 가이드

ORA-02292
2026년 08월 16일 | DBMS Error 가이드

이 글에서 다루는 내용

ORA-02292 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

ORA-02292 integrity constraint violated – child record found 는?

ORA-02292 에러는 Oracle 데이터베이스에서 부모 테이블의 레코드를 삭제하거나 수정하려 할 때, 해당 레코드를 참조하는 자식 테이블의 레코드가 존재할 경우 발생하는 참조 무결성(Referential Integrity) 위반 에러입니다. 외래 키(Foreign Key) 제약 조건이 설정된 환경에서 부모 레코드를 먼저 지우려 할 때 Oracle이 데이터 일관성을 보호하기 위해 이 에러를 발생시킵니다. 예를 들어 ORDERS 테이블에 참조되고 있는 CUSTOMERS 테이블의 고객 레코드를 삭제하려 할 때 전형적으로 나타납니다.


주요 발생 원인

  • 자식 레코드가 존재하는 부모 레코드 삭제 시도

가장 흔한 원인입니다. 부모 테이블(예: CUSTOMERS)의 특정 행을 DELETE 하려는데, 자식 테이블(예: ORDERS)에 해당 부모의 기본 키(Primary Key)를 참조하는 외래 키(Foreign Key) 컬럼 값이 하나 이상 존재하는 상황입니다. Oracle은 참조 무결성을 지키기 위해 자식 레코드가 남아있는 한 부모 레코드의 삭제를 허용하지 않습니다. 이는 고아(Orphan) 레코드 발생을 원천 차단하기 위한 정상적인 동작입니다.

  • 부모 레코드의 기본 키(PK) 값 변경 시도

부모 테이블의 기본 키 컬럼 값을 UPDATE 하려 할 때도 동일한 에러가 발생할 수 있습니다. 자식 테이블이 기존 PK 값을 외래 키로 참조하고 있는 경우, 부모의 PK를 변경하면 자식 레코드들이 더 이상 유효한 부모를 찾을 수 없게 되어 무결성이 깨집니다. 특히 제약 조건 생성 시 ON UPDATE CASCADE 옵션을 명시하지 않은 경우에는 PK 변경 자체가 차단됩니다.

  • 배치 처리 또는 대량 삭제 시 처리 순서 오류

데이터 이관, 배치 삭제, 혹은 테이블 초기화(TRUNCATE 대신 DELETE 사용) 작업 시 자식 테이블보다 부모 테이블을 먼저 처리하는 순서 실수가 원인이 됩니다. 여러 테이블 간의 복잡한 참조 관계를 파악하지 못한 채 단순히 대상 테이블만 DELETE 하려 할 때 자주 발생합니다. 특히 여러 단계의 부모-자식 관계(계층형 참조)가 있는 경우 처리 순서를 잘못 잡으면 연쇄적으로 에러가 발생합니다.


해결 방법

방법 1: 자식 레코드를 먼저 삭제 후 부모 레코드 삭제

가장 안전하고 권장되는 방법입니다. 자식 테이블의 관련 레코드를 먼저 삭제한 뒤 부모 레코드를 삭제합니다.

-- 1단계: 자식 테이블(ORDERS)에서 해당 고객의 주문 먼저 삭제
DELETE FROM ORDERS
WHERE CUSTOMER_ID = 1001;

-- 2단계: 부모 테이블(CUSTOMERS)에서 고객 레코드 삭제
DELETE FROM CUSTOMERS
WHERE CUSTOMER_ID = 1001;

-- 변경사항 확정
COMMIT;

계층이 여러 단계인 경우에는 가장 하위 자식부터 순서대로 삭제합니다.

-- 3단계 계층 예시: ORDER_ITEMS → ORDERS → CUSTOMERS
DELETE FROM ORDER_ITEMS
WHERE ORDER_ID IN (SELECT ORDER_ID FROM ORDERS WHERE CUSTOMER_ID = 1001);

DELETE FROM ORDERS
WHERE CUSTOMER_ID = 1001;

DELETE FROM CUSTOMERS
WHERE CUSTOMER_ID = 1001;

COMMIT;

방법 2: 외래 키 제약 조건에 ON DELETE CASCADE 설정

부모 레코드 삭제 시 자식 레코드도 자동으로 삭제되도록 제약 조건을 재설정할 수 있습니다. 단, 이 방법은 의도치 않은 데이터 삭제를 유발할 수 있으므로 비즈니스 요건을 충분히 검토한 후 적용해야 합니다.

-- 기존 외래 키 제약 조건 확인
SELECT CONSTRAINT_NAME, TABLE_NAME, R_CONSTRAINT_NAME, DELETE_RULE
FROM USER_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'R'
  AND TABLE_NAME = 'ORDERS';

-- 기존 제약 조건 삭제
ALTER TABLE ORDERS DROP CONSTRAINT FK_ORDERS_CUSTOMER_ID;

-- ON DELETE CASCADE 옵션을 포함하여 외래 키 재생성
ALTER TABLE ORDERS
ADD CONSTRAINT FK_ORDERS_CUSTOMER_ID
FOREIGN KEY (CUSTOMER_ID)
REFERENCES CUSTOMERS(CUSTOMER_ID)
ON DELETE CASCADE;

방법 3: 일시적으로 제약 조건 비활성화 (대량 작업 시)

대량 데이터 이관이나 배치 작업 시 일시적으로 제약 조건을 비활성화할 수 있습니다. 단, 작업 완료 후 반드시 재활성화해야 하며, 데이터 무결성 검증도 필수입니다.

-- 제약 조건 비활성화
ALTER TABLE ORDERS DISABLE CONSTRAINT FK_ORDERS_CUSTOMER_ID;

-- 부모 레코드 삭제 작업 수행
DELETE FROM CUSTOMERS WHERE CUSTOMER_ID = 1001;

-- 제약 조건 재활성화 (VALIDATE: 기존 데이터도 검증)
ALTER TABLE ORDERS ENABLE CONSTRAINT FK_ORDERS_CUSTOMER_ID;

-- 또는 NOVALIDATE 옵션 (기존 데이터는 검증 제외, 신규 데이터만 검증)
-- ALTER TABLE ORDERS ENABLE NOVALIDATE CONSTRAINT FK_ORDERS_CUSTOMER_ID;

방법 4: 자식 레코드 존재 여부 사전 확인 쿼리

삭제 전 자식 레코드가 존재하는지 먼저 확인하는 습관을 들이면 에러를 미연에 방지할 수 있습니다.

-- 삭제 대상 부모 레코드를 참조하는 자식 레코드 수 확인
SELECT COUNT(*) AS CHILD_COUNT
FROM ORDERS
WHERE CUSTOMER_ID = 1001;

-- 참조 관계 전체 파악 (USER_CONSTRAINTS 활용)
SELECT A.TABLE_NAME        AS CHILD_TABLE,
       A.CONSTRAINT_NAME   AS FK_NAME,
       A.R_CONSTRAINT_NAME AS REF_CONSTRAINT,
       B.TABLE_NAME        AS PARENT_TABLE
FROM USER_CONSTRAINTS A
JOIN USER_CONSTRAINTS B
  ON A.R_CONSTRAINT_NAME = B.CONSTRAINT_NAME
WHERE B.TABLE_NAME = 'CUSTOMERS'
  AND A.CONSTRAINT_TYPE = 'R';

예방 방법

  • 삭제/수정 작업 전 참조 관계 파악 자동화

운영 환경에서 대량 삭제나 수정 작업을 수행하기 전에는 반드시 USER_CONSTRAINTS 또는 ALL_CONSTRAINTS 딕셔너리 뷰를 조회하여 해당 테이블과 연관된 모든 외래 키 관계를 파악하는 프로세스를 표준화해야 합니다. 아래와 같은 참조 관계 조회 스크립트를 사전에 실행하는 것을 팀 내 공식 작업 절차로 정착시키는 것이 좋습니다.

“`sql

— 특정 테이블을 참조하는 모든 자식 테이블 및 컬럼 조회

SELECT C.TABLE_NAME AS CHILD_TABLE,

CC.COLUMN_NAME AS CHILD_COLUMN,

P.TABLE_NAME AS PARENT_TABLE,

PC.COLUMN_NAME AS PARENT_COLUMN,

C.DELETE_RULE

FROM USER_CONSTRAINTS C

JOIN USER_CONS_COLUMNS CC ON C.CONSTRAINT_NAME = CC.CONSTRAINT_NAME

JOIN USER_CONSTRAINTS P ON C.R_CONSTRAINT_NAME = P.CONSTRAINT_NAME

JOIN USER_CONS_COLUMNS PC ON P.CONSTRAINT_NAME = PC.CONSTRAINT_NAME

WHERE P.TABLE_NAME = ‘CUSTOMERS’ — 확인할 부모 테이블명

AND C.CONSTRAINT_TYPE = ‘R’

ORDER BY C.TABLE_NAME;

“`

  • 개발/테스트 단계에서 외래 키 제약 조건 전략 명확화

설계 단계에서 ON DELETE CASCADE, ON DELETE SET NULL, 혹은 기본 제한(RESTRICT) 중 어떤 전략을 사용할지 비즈니스 규칙에 맞게 명확히 정의하고 문서화해야 합니다. 특히 DELETE CASCADE는 강력하지만 연쇄 삭제로 인한 대규모 데이터 손실 위험이 있으므로, 중요 데이터 테이블에는 적용 여부를 신중하게 결정해야 합니다. 운영 배포 전 테스트 환경에서 다양한 삭제 시나리오를 반드시 검증하는 프로세스를 수립하는 것이 바람직합니다.


관련 에러

  • ORA-02291: integrity constraint violated - parent key not found — ORA-02292의 반대 상황으로, 자식 테이블에 INSERT 또는 UPDATE 할 때 참조하는 부모 키 값이 부모 테이블에 존재하지 않을 경우 발생합니다.
  • ORA-02290: check constraint violated — CHECK 제약 조건을 위반했을 때 발생하는 에러로, 무결성 제약 조건 위반 계열의 에러입니다.
  • ORA-00001: unique constraint violated — UNIQUE 또는 PRIMARY KEY 제약 조건 위반 시 발생하며, 참조 무결성 관련 작업 시 함께 만날 수 있습니다.

DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기