2026년 08월 14일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-02260 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-02260 table can have only one primary key 는?
ORA-02260 에러는 하나의 테이블에 기본 키(Primary Key)를 두 개 이상 정의하려 할 때 발생하는 Oracle 데이터베이스 오류입니다. 관계형 데이터베이스의 기본 원칙에 따라 테이블은 단 하나의 기본 키 제약 조건만 가질 수 있으며, 이를 위반하는 DDL 또는 ALTER 문을 실행할 경우 즉시 해당 에러가 발생합니다. 실무에서는 테이블 생성 스크립트 중복 실행, ALTER TABLE 문 오류, 또는 마이그레이션 작업 중 제약 조건이 이미 존재하는 상황에서 추가 정의를 시도할 때 자주 마주치는 에러입니다.
주요 발생 원인
1. 이미 기본 키가 존재하는 테이블에 ALTER TABLE로 기본 키를 추가하려는 경우
가장 흔하게 발생하는 원인으로, 테이블에 이미 PRIMARY KEY 제약 조건이 설정되어 있음에도 불구하고 ALTER TABLE … ADD CONSTRAINT … PRIMARY KEY 구문을 다시 실행할 때 발생합니다. 특히 배포 스크립트나 마이그레이션 스크립트를 멱등성(Idempotent) 처리 없이 반복 실행하는 환경에서 빈번하게 나타납니다. DBA 또는 개발자가 테이블의 현재 제약 조건 상태를 확인하지 않고 스크립트를 그대로 재실행하는 것이 대표적인 실수입니다.
2. CREATE TABLE 구문 내에서 기본 키를 두 번 이상 정의한 경우
테이블 생성 DDL 스크립트를 작성하는 과정에서 컬럼 레벨 제약 조건과 테이블 레벨 제약 조건에 각각 PRIMARY KEY를 지정하거나, 또는 CONSTRAINT 절을 중복으로 작성하는 실수를 범할 때 발생합니다. 특히 여러 명의 개발자가 동일한 스크립트를 편집하거나 레거시 DDL 스크립트를 수정하는 과정에서 이런 실수가 발생하기 쉽습니다. ORM(Object-Relational Mapping) 도구나 ERD 자동 생성 도구에서 내보낸 스크립트가 중복 정의를 포함하는 경우도 있으므로 반드시 검토가 필요합니다.
3. 데이터베이스 마이그레이션 또는 임포트 작업 중 제약 조건 충돌
Oracle Data Pump(impdp), SQL*Loader 또는 다른 마이그레이션 도구를 사용하여 데이터를 임포트할 때, 대상 테이블에 이미 기본 키 제약 조건이 존재하는 상태에서 소스의 기본 키 정의까지 함께 임포트하려 할 경우 충돌이 발생합니다. 또한 스키마 복제 작업이나 테이블 구조 변경 후 제약 조건 재생성 스크립트를 실행할 때도 동일한 상황이 발생할 수 있습니다. 이 경우 에러 로그를 꼼꼼히 분석하고 기존 제약 조건을 먼저 DROP한 후 재생성하는 절차가 필요합니다.
해결 방법
원인 1 해결: 기존 기본 키 확인 후 처리
먼저 현재 테이블에 정의된 기본 키 제약 조건을 조회합니다.
-- 현재 테이블의 기본 키 제약 조건 확인
SELECT constraint_name, constraint_type, status
FROM user_constraints
WHERE table_name = 'EMPLOYEES'
AND constraint_type = 'P';
-- 기본 키를 구성하는 컬럼 확인
SELECT ucc.constraint_name, ucc.column_name, ucc.position
FROM user_cons_columns ucc
JOIN user_constraints uc ON ucc.constraint_name = uc.constraint_name
WHERE uc.table_name = 'EMPLOYEES'
AND uc.constraint_type = 'P'
ORDER BY ucc.position;
기존 기본 키를 삭제하고 새로운 기본 키를 생성해야 할 경우:
-- 기존 기본 키 제약 조건 삭제 (인덱스 함께 삭제)
ALTER TABLE employees
DROP CONSTRAINT pk_employees CASCADE;
-- 새로운 기본 키 제약 조건 추가
ALTER TABLE employees
ADD CONSTRAINT pk_employees PRIMARY KEY (employee_id)
USING INDEX TABLESPACE users_idx;
원인 2 해결: CREATE TABLE 스크립트 중복 정의 수정
잘못된 예시와 올바른 예시를 비교합니다.
-- ❌ 잘못된 예: 컬럼 레벨과 테이블 레벨 모두에 PRIMARY KEY 정의
CREATE TABLE orders (
order_id NUMBER PRIMARY KEY, -- 컬럼 레벨 기본 키
order_date DATE NOT NULL,
customer_id NUMBER NOT NULL,
CONSTRAINT pk_orders PRIMARY KEY (order_id) -- 중복 정의 → ORA-02260 발생
);
-- ✅ 올바른 예 1: 컬럼 레벨에만 정의
CREATE TABLE orders (
order_id NUMBER PRIMARY KEY,
order_date DATE NOT NULL,
customer_id NUMBER NOT NULL
);
-- ✅ 올바른 예 2: 테이블 레벨에만 정의 (복합 기본 키 포함, 권장 방식)
CREATE TABLE orders (
order_id NUMBER NOT NULL,
order_date DATE NOT NULL,
customer_id NUMBER NOT NULL,
CONSTRAINT pk_orders PRIMARY KEY (order_id)
);
-- ✅ 복합 기본 키(Composite Primary Key) 올바른 정의
CREATE TABLE order_items (
order_id NUMBER NOT NULL,
item_seq NUMBER NOT NULL,
product_id NUMBER NOT NULL,
quantity NUMBER DEFAULT 1,
CONSTRAINT pk_order_items PRIMARY KEY (order_id, item_seq)
);
원인 3 해결: 마이그레이션 작업 시 안전한 절차
-- Step 1: 대상 테이블의 모든 제약 조건 확인
SELECT constraint_name, constraint_type, status, validated
FROM user_constraints
WHERE table_name = 'TARGET_TABLE'
ORDER BY constraint_type;
-- Step 2: 기존 기본 키 삭제 (KEEP INDEX 옵션으로 인덱스는 유지)
ALTER TABLE target_table
DROP CONSTRAINT pk_target_table KEEP INDEX;
-- Step 3: 마이그레이션 또는 임포트 작업 수행 후 기본 키 재생성
ALTER TABLE target_table
ADD CONSTRAINT pk_target_table PRIMARY KEY (id_column);
-- Step 4: 제약 조건 정상 생성 확인
SELECT constraint_name, status, validated, last_change
FROM user_constraints
WHERE table_name = 'TARGET_TABLE'
AND constraint_type = 'P';
스크립트 멱등성 처리 (재실행 안전 패턴)
-- 기본 키가 존재하지 않을 때만 추가하는 안전한 스크립트 패턴
DECLARE
v_count NUMBER;
BEGIN
SELECT COUNT(*)
INTO v_count
FROM user_constraints
WHERE table_name = 'EMPLOYEES'
AND constraint_type = 'P';
IF v_count = 0 THEN
EXECUTE IMMEDIATE
'ALTER TABLE employees
ADD CONSTRAINT pk_employees PRIMARY KEY (employee_id)';
DBMS_OUTPUT.PUT_LINE('Primary Key 제약 조건이 생성되었습니다.');
ELSE
DBMS_OUTPUT.PUT_LINE('Primary Key 제약 조건이 이미 존재합니다. 건너뜁니다.');
END IF;
END;
/
예방 방법
1. DDL 스크립트 실행 전 제약 조건 존재 여부를 반드시 사전 점검하라
모든 DDL 배포 스크립트는 실행 전 대상 테이블의 제약 조건 상태를 확인하는 사전 점검 쿼리를 포함해야 합니다. 특히 CI/CD 파이프라인이나 자동화 배포 환경에서는 위에서 소개한 멱등성 처리 패턴(PL/SQL 블록을 활용한 조건 체크 후 실행)을 표준으로 채택하여, 스크립트가 여러 번 실행되더라도 에러가 발생하지 않도록 설계해야 합니다. 팀 내 DDL 스크립트 리뷰 프로세스를 수립하고 Peer Review를 의무화하는 것도 좋은 방법입니다.
2. 테이블 설계 단계에서 ERD 및 데이터 사전을 통해 제약 조건을 명확히 문서화하라
개발 초기 단계에서 ERD(Entity-Relationship Diagram) 도구를 활용하여 기본 키를 명확히 정의하고, 데이터 사전(Data Dictionary)에 모든 제약 조건을 문서화하는 습관을 들여야 합니다. Oracle SQL Developer, ERwin, DA# 등의 도구는 중복 제약 조건을 시각적으로 탐지하는 기능을 제공하므로 적극 활용하시기 바랍니다. 또한 운영 환경과 개발 환경의 스키마 동기화 상태를 주기적으로 비교하는 것도 예방에 큰 도움이 됩니다.
관련 에러
- ORA-02261:
such unique or primary key already exists in the table— 기본 키와 유사한 유니크 키 중복 정의 시 발생하는 에러로 ORA-02260과 함께 자주 등장합니다. - ORA-02270:
no matching unique or primary key for this column-list— 외래 키(Foreign Key) 정의 시 참조 대상 테이블에 기본 키 또는 유니크 키가 없을 때 발생하며, 기본 키 관련 작업 중 연쇄적으로 발생할 수 있습니다. - ORA-00001:
unique constraint violated— 기본 키 제약 조건이 정상적으로 존재하는 상태에서 중복 값을 INSERT할 때 발생하는 에러로, 기본 키 재설계 후 데이터 무결성 검증 단계에서 나타날 수 있습니다. - ORA-02275:
such a referential constraint already exists in the table— 외래 키 중복 정의 시 발생하며, 기본 키와 외래 키를 동시에 재구성하는 마이그레이션 작업에서 함께 발생하는 경우가 많습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.