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

ORA-02293
2026년 08월 17일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-02293 cannot validate – check constraint violated 는?

ORA-02293 에러는 기존 테이블에 CHECK 제약 조건을 추가하거나 비활성화된 CHECK 제약 조건을 활성화(ENABLE VALIDATE)하려 할 때, 이미 테이블에 저장된 데이터 중 해당 제약 조건을 위반하는 행이 존재할 경우 발생합니다. Oracle은 제약 조건을 활성화하는 시점에 테이블의 모든 기존 데이터를 검증하며, 단 하나의 행이라도 조건을 충족하지 못하면 이 에러와 함께 작업을 중단합니다. 이 에러는 주로 대용량 데이터를 보유한 운영 테이블에 뒤늦게 비즈니스 규칙을 적용하거나, 데이터 마이그레이션 이후 제약 조건을 재활성화하는 상황에서 빈번하게 발생합니다.


주요 발생 원인

1. 기존 데이터가 새로 추가하는 CHECK 제약 조건을 위반하는 경우

가장 흔한 원인으로, 운영 중인 테이블에 새로운 비즈니스 규칙을 CHECK 제약 조건으로 추가할 때 발생합니다. 예를 들어 SALARY 컬럼에 SALARY > 0 조건을 추가하려는데 이미 0 또는 음수 급여 데이터가 존재하는 경우, Oracle은 해당 ALTER TABLE 문을 즉시 실패 처리합니다.

2. 비활성화(DISABLE) 상태의 제약 조건을 ENABLE VALIDATE로 전환할 때

제약 조건이 DISABLE 상태인 동안 데이터 입력 시 검증이 수행되지 않아, 제약 조건을 위반하는 데이터가 축적될 수 있습니다. 이후 ALTER TABLE ... ENABLE CONSTRAINT 명령으로 제약 조건을 다시 활성화하려 하면, 쌓여있던 불량 데이터로 인해 ORA-02293이 발생합니다.

3. 데이터 마이그레이션 또는 대량 INSERT 이후 제약 조건 적용

다른 시스템이나 레거시 데이터베이스에서 데이터를 마이그레이션할 때 제약 조건을 우회하여 데이터를 적재하는 경우가 많습니다. 마이그레이션 완료 후 제약 조건을 활성화하는 과정에서 원본 시스템의 데이터 품질 문제가 그대로 노출되어 이 에러가 발생합니다.


해결 방법

원인 1 해결: 위반 데이터 식별 및 수정 후 제약 조건 추가

먼저 어떤 데이터가 제약 조건을 위반하는지 확인합니다.

-- 위반 데이터 조회 (SALARY <= 0 인 데이터 확인)
SELECT employee_id, salary
FROM   employees
WHERE  salary <= 0
OR     salary IS NULL;

위반 데이터를 수정하거나 삭제한 후 제약 조건을 추가합니다.

-- 위반 데이터 수정 (예: 최솟값으로 보정)
UPDATE employees
SET    salary = 1
WHERE  salary <= 0;

COMMIT;

-- 데이터 정제 후 제약 조건 추가
ALTER TABLE employees
ADD CONSTRAINT chk_salary_positive CHECK (salary > 0);

원인 2 해결: ENABLE NOVALIDATE 옵션 활용

기존 데이터는 그대로 두고 신규 데이터에만 제약 조건을 적용해야 하는 상황이라면, ENABLE NOVALIDATE 옵션을 사용합니다. 이 옵션은 기존 데이터 검증을 건너뛰고 이후 INSERT/UPDATE되는 데이터에만 제약 조건을 적용합니다.

-- 기존 데이터 검증 없이 제약 조건 활성화
ALTER TABLE employees
ENABLE NOVALIDATE CONSTRAINT chk_salary_positive;

-- 제약 조건 상태 확인
SELECT constraint_name,
       constraint_type,
       status,
       validated
FROM   user_constraints
WHERE  table_name = 'EMPLOYEES';

원인 3 해결: EXCEPTIONS 테이블을 활용한 위반 데이터 추적

대량 데이터에서 어떤 행이 위반하는지 파악하기 어려울 때는 Oracle의 EXCEPTIONS 테이블 기능을 활용합니다.

-- EXCEPTIONS 테이블 생성 (최초 1회)
@$ORACLE_HOME/rdbms/admin/utlexcpt.sql

-- 위반 데이터를 EXCEPTIONS 테이블에 수집하며 제약 조건 활성화 시도
ALTER TABLE employees
ENABLE VALIDATE CONSTRAINT chk_salary_positive
EXCEPTIONS INTO exceptions;

-- 위반 행 상세 조회
SELECT e.row_id,
       emp.employee_id,
       emp.salary,
       e.constraint
FROM   exceptions e,
       employees emp
WHERE  e.row_id = emp.rowid
AND    e.table_name = 'EMPLOYEES';

-- 조회 결과를 바탕으로 데이터 수정
UPDATE employees
SET    salary = ABS(salary) + 1
WHERE  rowid IN (SELECT row_id FROM exceptions
                 WHERE  table_name = 'EMPLOYEES');

COMMIT;

-- 수정 후 재시도
ALTER TABLE employees
ENABLE VALIDATE CONSTRAINT chk_salary_positive;

예방 방법

1. 제약 조건 추가 전 사전 검증 쿼리 실행을 표준 절차화

새로운 CHECK 제약 조건을 DDL로 적용하기 전, 반드시 해당 조건의 역(NOT 조건)으로 데이터를 조회하는 사전 검증 단계를 배포 절차에 포함시킵니다. CI/CD 파이프라인이나 DBA 변경 관리 프로세스에 이 단계를 필수 게이트로 설정하면 운영 환경에서의 돌발 에러를 원천 차단할 수 있습니다.

-- 제약 조건 적용 전 위반 건수 사전 확인 (0건이어야 안전)
SELECT COUNT(*) AS violation_count
FROM   employees
WHERE  NOT (salary > 0)
OR     salary IS NULL;

2. 데이터 마이그레이션 시 제약 조건 비활성화·재활성화 전략 수립

마이그레이션 시에는 DISABLE NOVALIDATE로 제약 조건을 비활성화하고 데이터를 적재한 뒤, 데이터 품질 검증 스크립트를 실행하여 불량 데이터를 정제한 후 ENABLE VALIDATE로 전환하는 3단계 절차를 문서화하고 반드시 준수합니다. 이 절차를 건너뛰고 마이그레이션 완료 후 제약 조건을 한 번에 활성화하려다 ORA-02293이 발생하는 사례가 실무에서 매우 빈번합니다.


관련 에러

  • ORA-02290: CHECK 제약 조건 위반 — INSERT 또는 UPDATE 시점에 단건 데이터가 CHECK 조건을 만족하지 못할 때 발생하며, ORA-02293과 달리 런타임 DML 오류입니다.
  • ORA-02291: 무결성 제약 조건 위반 (부모 키 없음) — FOREIGN KEY 제약 조건 관련 에러로, 참조 대상 부모 행이 없을 때 발생합니다.
  • ORA-02292: 무결성 제약 조건 위반 (자식 레코드 존재) — 부모 행 삭제 시 자식 행이 남아있을 때 발생합니다.
  • ORA-02296: 제약 조건 활성화 불가 — NULL 값이 NOT NULL 제약 조건을 위반할 때 발생하며, ORA-02293의 NOT NULL 버전에 해당합니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기