[Oracle] ORA-02291 & ORA-00001: 무결성 제약조건 위배 완벽 이해

데이터베이스의 가장 중요한 역할은 데이터를 ‘안전하고’, ‘일관되게’ 보관하는 것입니다. 이를 위해 Oracle은 **무결성 제약조건(Integrity Constraint)**이라는 규칙을 사용합니다. ORA-00001ORA-02291 오류는 이 규칙이 위배되었을 때 발생하는, 데이터의 정합성을 지키기 위한 필수적인 신호입니다.

이번 포스팅에서는 데이터 모델의 핵심인 이 두 제약조건 관련 오류의 의미를 명확히 이해하고, 발생 원인과 해결 방안을 심층적으로 다룹니다.


Part 1: ORA-00001: unique constraint (...) violated (고유 제약조건 위배) 🔑

이 오류는 테이블 내에서 데이터의 유일성이 깨졌을 때 발생합니다. 즉, 기본키(Primary Key) 또는 **고유키(Unique Key)**로 지정된 컬럼에 이미 존재하는 값을 또다시 INSERT하거나 UPDATE하려고 시도할 때 발생합니다.

  • 기본키(Primary Key): 테이블에서 각 행(Row)을 유일하게 식별하는 값. (예: 사원번호, 부서코드). NULL 값을 허용하지 않습니다.
  • 고유키(Unique Key): 값의 중복은 허용하지 않지만, NULL 값은 허용(보통 한 번만)하는 제약조건. (예: 이메일 주소)

발생 시나리오 및 해결 방안

  • 발생 예시: DEPARTMENTS 테이블의 DEPT_NO 컬럼이 기본키(PK)일 때, 이미 존재하는 부서 번호를 추가하려는 경우
-- 현재 DEPARTMENTS 테이블 데이터 
-- DEPT_NO | DNAME 
-- --------|---------- 
-- 10      | ACCOUNTING 
-- 20      | RESEARCH 
-- 부서번호 10번을 다시 INSERT 시도 
INSERT INTO DEPARTMENTS (DEPT_NO, DNAME) VALUES (10, 'SALES'); 
-- ORA-00001: unique constraint (SCOTT.PK_DEPT) violated
  • 원인 분석: 기본키인 DEPT_NO 컬럼에 중복된 값 10을 입력하려고 시도했기 때문입니다.
  • 해결 및 디버깅:
    1. 데이터 사전 확인: 데이터를 입력하기 전에, 해당 키 값이 테이블에 이미 존재하는지 SELECT 문으로 확인하는 것이 가장 기본입니다.
    2. 시퀀스(Sequence) 사용 점검: 자동 증가 값이 필요한 기본키의 경우, SEQUENCE.NEXTVAL을 사용하지 않고 값을 직접 입력(Hard-coding)하는 과정에서 중복이 발생할 수 있습니다. 애플리케이션 로직이 시퀀스를 올바르게 사용하고 있는지 점검해야 합니다.
    3. 데이터 소스 검증: 외부 파일이나 다른 시스템으로부터 데이터를 가져와 입력(ETL)하는 경우, 원본 데이터 자체에 중복이 포함되어 있는지 먼저 확인해야 합니다.
SELECT COUNT(*) 
FROM DEPARTMENTS 
WHERE DEPT_NO = 10;

Part 2: ORA-02291: integrity constraint (...) violated - parent key not found (부모 키 없음) 🔗

이 오류는 테이블 간의 관계가 깨졌을 때 발생합니다. **외래키(Foreign Key)**로 지정된 자식 테이블의 컬럼에 값을 입력하려는데, 그 값이 부모 테이블의 기본키(또는 고유키)에 존재하지 않을 때 발생합니다.

예를 들어, ‘사원(EMPLOYEES)’ 테이블에 ‘부서번호(DEPT_NO)’를 입력하려면, 해당 부서 번호가 반드시 ‘부서(DEPARTMENTS)’ 테이블에 먼저 존재해야 한다는 규칙입니다.

발생 시나리오 및 해결 방안

  • 발생 예시: EMPLOYEES 테이블의 DEPT_NODEPARTMENTS 테이블의 DEPT_NO를 참조하는 외래키(FK)일 때, 존재하지 않는 부서 번호를 사원에게 할당하는 경우
-- DEPARTMENTS 테이블에는 부서번호 10, 20만 존재한다고 가정 
-- 사원 정보에 존재하지 않는 부서번호 30을 INSERT 시도 
INSERT INTO EMPLOYEES (EMP_NO, ENAME, DEPT_NO) 
VALUES (8000, 'KIM', 30); 
-- ORA-02291: integrity constraint (SCOTT.FK_DEPTNO) violated - parent key not found
  • 원인 분석: EMPLOYEES 테이블에 입력하려는 DEPT_NO30이, 관계의 기준이 되는 부모 테이블(DEPARTMENTS)에 존재하지 않기 때문입니다.
  • 해결 및 디버깅:
    1. 부모 키 존재 확인: 자식 테이블에 데이터를 입력하기 전에, 외래키로 사용할 값이 부모 테이블에 존재하는지 SELECT 문으로 먼저 확인해야 합니다.
    2. 데이터 입력 순서 준수: 반드시 **부모 테이블에 데이터를 먼저 INSERT**한 후, 해당 키를 참조하는 자식 테이블의 데이터를 INSERT해야 합니다.
    3. 데이터 수정/삭제 시나리오: 부모 테이블의 키 값을 UPDATE하거나 행을 DELETE할 때도 자식 테이블이 해당 키를 참조하고 있다면 제약조건 위배 오류가 발생할 수 있습니다. (이 경우 ON DELETE CASCADE 같은 옵션으로 동작을 제어할 수 있습니다.)
SELECT COUNT(*) 
FROM DEPARTMENTS 
WHERE DEPT_NO = 30;

요약 ✅

  • ORA-00001테이블 내의 유일성을 보장하는 오류입니다. (예: 모든 국민의 주민등록번호는 달라야 한다.)
  • ORA-02291테이블 간의 관계를 보장하는 오류입니다. (예: 학생의 학적부에 기재된 학과 코드는 반드시 학교의 학과 목록에 존재해야 한다.)