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

ORA-01452
2026년 07월 16일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-01452 cannot CREATE UNIQUE INDEX; duplicate keys found 는?

ORA-01452 에러는 유니크 인덱스(UNIQUE INDEX)를 생성하려고 할 때, 대상 컬럼(또는 컬럼 조합)에 이미 중복된 값이 존재할 경우 발생하는 오류입니다. Oracle은 유니크 인덱스의 특성상 동일한 키 값이 두 개 이상 존재하는 것을 허용하지 않으므로, 인덱스 생성 작업 자체를 거부합니다. 주로 기존 테이블에 사후(After-the-fact)로 유니크 제약조건이나 유니크 인덱스를 추가하려 할 때, 또는 PRIMARY KEY나 UNIQUE CONSTRAINT를 뒤늦게 정의할 때 자주 마주치게 됩니다.


주요 발생 원인

  • 기존 테이블 데이터에 중복 값이 존재하는 경우

가장 흔한 원인입니다. 운영 중인 테이블에 데이터가 쌓인 상태에서 특정 컬럼에 유니크 인덱스나 PRIMARY KEY를 추가하려 할 때, 이미 해당 컬럼에 동일한 값이 여러 행에 걸쳐 존재하면 이 에러가 발생합니다. 예를 들어 EMPLOYEE 테이블의 EMAIL 컬럼에 같은 이메일 주소가 두 건 이상 입력되어 있는 상태에서 유니크 인덱스를 생성하려 하면 즉시 ORA-01452가 발생합니다.

  • NULL 처리 오해 및 복합 컬럼 인덱스에서의 중복

단일 컬럼에서는 NULL 값이 유니크 인덱스에서 허용되지만, 복합 유니크 인덱스(Composite Unique Index)에서는 NULL이 아닌 나머지 컬럼 값들의 조합이 동일할 경우 중복으로 간주됩니다. 예를 들어 (DEPT_ID, EMP_CODE) 복합 유니크 인덱스를 생성할 때, DEPT_ID가 같고 EMP_CODE도 동일한 행이 두 개 이상 존재한다면 에러가 발생합니다. 복합 키 구성 시 각 컬럼의 데이터 분포를 사전에 반드시 확인해야 합니다.

  • 데이터 마이그레이션 또는 대량 INSERT 이후 인덱스 재생성 시

대량 데이터 적재(Bulk Load) 또는 다른 시스템으로부터 데이터 마이그레이션 작업 후, 비활성화(Disable)되어 있던 유니크 인덱스나 제약조건을 다시 활성화(Enable)하거나 재생성하려 할 때 발생하기도 합니다. ETL 작업이나 INSERT /+ APPEND / 힌트를 사용한 대량 삽입 과정에서 중복 데이터가 유입될 수 있으며, 이후 인덱스를 재빌드(REBUILD)하거나 제약조건을 ENABLE할 때 이 에러를 만나게 됩니다.


해결 방법

1단계: 중복 데이터 탐색

먼저 어떤 값이 중복되어 있는지 정확히 파악해야 합니다.

-- 단일 컬럼 중복 확인
SELECT email, COUNT(*) AS cnt
FROM   employees
GROUP  BY email
HAVING COUNT(*) > 1
ORDER  BY cnt DESC;

-- 복합 컬럼 중복 확인
SELECT dept_id, emp_code, COUNT(*) AS cnt
FROM   employees
GROUP  BY dept_id, emp_code
HAVING COUNT(*) > 1
ORDER  BY cnt DESC;

2단계: 중복 행 상세 조회

중복된 값을 가진 실제 행(ROW)을 확인합니다. ROWID를 활용하면 같은 값을 가진 행 중 어느 것을 남길지 판단할 수 있습니다.

-- 중복 행 상세 조회 (ROWID 포함)
SELECT rowid, employee_id, email, created_date
FROM   employees
WHERE  email IN (
    SELECT email
    FROM   employees
    GROUP  BY email
    HAVING COUNT(*) > 1
)
ORDER  BY email, created_date;

3단계: 중복 데이터 정리

중복 데이터를 정리하는 방법은 비즈니스 규칙에 따라 달라집니다. 일반적으로는 가장 최근에 입력된 행 또는 가장 오래된 행 하나만 남기고 나머지를 삭제합니다.

-- 방법 1: 가장 최신 ROWID만 남기고 나머지 중복 행 삭제
DELETE FROM employees
WHERE  rowid NOT IN (
    SELECT MAX(rowid)
    FROM   employees
    GROUP  BY email
);

-- 방법 2: ROW_NUMBER() 분석 함수를 이용한 삭제 (권장)
DELETE FROM employees
WHERE  rowid IN (
    SELECT rowid
    FROM (
        SELECT rowid,
               ROW_NUMBER() OVER (
                   PARTITION BY email
                   ORDER BY created_date DESC, employee_id DESC
               ) AS rn
        FROM   employees
    )
    WHERE rn > 1
);

-- 삭제 후 반드시 COMMIT
COMMIT;

4단계: 유니크 인덱스 또는 제약조건 생성

중복 데이터를 모두 제거한 후 인덱스를 생성합니다.

-- 유니크 인덱스 생성
CREATE UNIQUE INDEX idx_emp_email
ON employees (email);

-- 또는 UNIQUE CONSTRAINT 추가 (내부적으로 유니크 인덱스 자동 생성)
ALTER TABLE employees
ADD CONSTRAINT uq_emp_email UNIQUE (email);

-- 비활성화된 제약조건을 다시 활성화할 경우
ALTER TABLE employees
ENABLE CONSTRAINT uq_emp_email;

5단계: 마이그레이션 환경에서 중복 처리 후 재활성화

ETL 또는 마이그레이션 이후 재활성화가 필요한 경우입니다.

-- 제약조건 비활성화 후 데이터 적재
ALTER TABLE employees DISABLE CONSTRAINT uq_emp_email;

-- 데이터 적재 (예시)
INSERT INTO employees (employee_id, email, created_date)
SELECT employee_id, email, SYSDATE FROM employees_staging;
COMMIT;

-- 중복 제거 후 재활성화
ALTER TABLE employees ENABLE NOVALIDATE CONSTRAINT uq_emp_email;
-- 또는 전체 검증 포함 재활성화
ALTER TABLE employees ENABLE VALIDATE CONSTRAINT uq_emp_email;

예방 방법

  • 테이블 설계 단계에서 제약조건을 선제적으로 정의하라

테이블을 처음 생성할 때부터 유니크해야 하는 컬럼에는 UNIQUE 또는 PRIMARY KEY 제약조건을 명시적으로 선언하는 것이 가장 확실한 예방책입니다. 데이터가 쌓인 이후에 제약조건을 추가하는 것은 항상 리스크를 수반합니다. 신규 테이블 설계 시 DDL 리뷰 프로세스를 도입하여 유니크 컬럼이 누락되지 않도록 관리하는 것을 권장합니다.

“`sql

— 테이블 생성 시부터 제약조건 선언

CREATE TABLE employees (

employee_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,

email VARCHAR2(100) NOT NULL,

emp_code VARCHAR2(20) NOT NULL,

created_date DATE DEFAULT SYSDATE,

CONSTRAINT uq_emp_email UNIQUE (email),

CONSTRAINT uq_emp_code UNIQUE (emp_code)

);

“`

  • 데이터 마이그레이션 전후로 중복 검증 스크립트를 표준 절차에 포함하라

ETL 작업이나 대량 데이터 적재 전·후에 반드시 중복 데이터 검증 쿼리를 실행하는 것을 표준 운영 절차(SOP)로 정착시켜야 합니다. 특히 소스 시스템에서 유니크 제약조건이 없었던 컬럼의 데이터를 가져올 때는 더욱 주의가 필요합니다. 아래와 같은 검증 스크립트를 파이프라인에 포함시켜 중복 발견 즉시 작업을 중단하도록 구성하는 것이 좋습니다.

“`sql

— 마이그레이션 전 중복 사전 검증 스크립트

DECLARE

v_dup_count NUMBER;

BEGIN

SELECT COUNT(*)

INTO v_dup_count

FROM (

SELECT email

FROM employees_staging

GROUP BY email

HAVING COUNT(*) > 1

);

IF v_dup_count > 0 THEN

RAISE_APPLICATION_ERROR(-20001,

‘Duplicate email found in staging: ‘ || v_dup_count || ‘ groups. Aborting migration.’);

END IF;

DBMS_OUTPUT.PUT_LINE(‘Validation passed. No duplicates found.’);

END;

/

“`


관련 에러

  • ORA-00001: unique constraint violated — 유니크 인덱스가 이미 존재하는 상태에서 중복 값을 INSERT 또는 UPDATE하려 할 때 발생하는 에러로, ORA-01452와 쌍을 이루는 대표적인 관련 에러입니다.
  • ORA-02299: cannot validate (schema.constraint) – duplicate keys foundALTER TABLE ... ENABLE CONSTRAINT 명령 실행 시 중복 데이터로 인해 제약조건 활성화에 실패할 때 발생합니다. ORA-01452와 원인이 동일하며 해결 방법도 동일합니다.
  • ORA-01408: such column list already indexed — 이미 동일한 컬럼 조합으로 인덱스가 존재할 때 발생하며, 유니크 인덱스 생성 시 함께 확인해야 할 에러입니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기