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

ORA-04004
2026년 08월 18일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-04004 MINVALUE must be less than MAXVALUE 는?

ORA-04004 에러는 Oracle 시퀀스(Sequence)를 생성하거나 변경할 때 MINVALUE가 MAXVALUE보다 크거나 같게 설정된 경우 발생하는 에러입니다. Oracle 시퀀스는 자동으로 증가하거나 감소하는 숫자를 생성하는 객체로, 그 동작 범위를 정의하는 MINVALUE와 MAXVALUE는 반드시 올바른 대소 관계를 유지해야 합니다. 즉, MINVALUE < MAXVALUE 조건이 항상 성립해야 하며, 이 조건을 위반할 경우 Oracle은 즉시 ORA-04004 에러를 반환합니다.

주요 발생 원인

  • CREATE SEQUENCE 또는 ALTER SEQUENCE 시 MINVALUE와 MAXVALUE 값을 잘못 지정한 경우

가장 흔한 원인으로, 시퀀스를 생성하거나 수정할 때 MINVALUE와 MAXVALUE 값을 실수로 반대로 입력하거나, 동일한 값으로 설정하는 경우입니다. 예를 들어, MINVALUE를 1000으로 설정하고 MAXVALUE를 100으로 설정하는 실수가 대표적입니다. 특히 대규모 배포 스크립트나 마이그레이션 작업 중 값 복사 오류로 인해 자주 발생하며, 운영 환경에서도 종종 나타납니다.

  • 역방향 시퀀스(Descending Sequence) 설정 시 혼동

감소하는 시퀀스(INCREMENT BY 음수)를 생성할 때 MINVALUE와 MAXVALUE의 개념을 혼동하여 잘못 설정하는 경우입니다. 역방향 시퀀스에서도 반드시 MINVALUE < MAXVALUE 규칙은 동일하게 적용됩니다. 많은 DBA들이 감소하는 시퀀스라면 MINVALUE가 MAXVALUE보다 커야 한다고 착각하지만, Oracle에서 MINVALUE와 MAXVALUE는 절대적인 범위를 의미하므로 이 규칙은 변하지 않습니다.

  • ALTER SEQUENCE로 기존 시퀀스 범위를 변경할 때 현재 값과의 충돌

기존에 운영 중인 시퀀스의 범위를 ALTER SEQUENCE로 변경할 때, 현재 시퀀스의 CURRVAL이나 NEXTVAL과 충돌하면서 MINVALUE, MAXVALUE 설정이 논리적으로 맞지 않는 상황이 발생할 수 있습니다. 예를 들어, 이미 사용 중인 시퀀스의 MAXVALUE를 현재 값보다 낮게 줄이거나, MINVALUE를 MAXVALUE보다 높게 올리려는 시도가 이에 해당합니다. 이 경우 시퀀스의 현재 상태를 먼저 확인하지 않고 무작정 ALTER를 실행하면 에러가 발생합니다.

해결 방법

원인 1 해결: MINVALUE와 MAXVALUE를 올바르게 지정

MINVALUE가 반드시 MAXVALUE보다 작아야 합니다. 아래 예제처럼 시퀀스를 올바르게 생성하세요.

-- 잘못된 예 (ORA-04004 발생)
CREATE SEQUENCE seq_test
    START WITH 1
    INCREMENT BY 1
    MINVALUE 1000   -- MINVALUE가 MAXVALUE보다 큼 → 에러!
    MAXVALUE 100
    NOCYCLE
    NOCACHE;

-- 올바른 예 (정상 동작)
CREATE SEQUENCE seq_test
    START WITH 1
    INCREMENT BY 1
    MINVALUE 1       -- MINVALUE < MAXVALUE 조건 충족
    MAXVALUE 999999999
    NOCYCLE
    NOCACHE;

원인 2 해결: 역방향 시퀀스(Descending Sequence) 올바르게 생성

감소하는 시퀀스를 만들 때도 MINVALUE < MAXVALUE 규칙은 동일하게 적용됩니다. INCREMENT BY에 음수 값을 사용하되, MINVALUE와 MAXVALUE의 범위는 올바르게 설정해야 합니다.

-- 잘못된 예 (ORA-04004 발생)
CREATE SEQUENCE seq_descending
    START WITH 1000
    INCREMENT BY -1
    MINVALUE 1000   -- MINVALUE와 MAXVALUE가 같음 → 에러!
    MAXVALUE 1000
    NOCYCLE;

-- 올바른 예 (감소하는 시퀀스)
CREATE SEQUENCE seq_descending
    START WITH 1000
    INCREMENT BY -1
    MINVALUE 1       -- MINVALUE < MAXVALUE 조건 유지
    MAXVALUE 1000
    NOCYCLE
    NOCACHE;

-- 실제 사용 확인
SELECT seq_descending.NEXTVAL FROM DUAL;  -- 1000
SELECT seq_descending.NEXTVAL FROM DUAL;  -- 999
SELECT seq_descending.NEXTVAL FROM DUAL;  -- 998

원인 3 해결: ALTER SEQUENCE 전 현재 시퀀스 상태 확인 후 변경

기존 시퀀스를 변경하기 전에 반드시 현재 상태를 조회하고, 논리적으로 올바른 값으로 변경해야 합니다.

-- 현재 시퀀스 상태 확인
SELECT SEQUENCE_NAME,
       MIN_VALUE,
       MAX_VALUE,
       INCREMENT_BY,
       LAST_NUMBER,
       CYCLE_FLAG,
       CACHE_SIZE
FROM   USER_SEQUENCES
WHERE  SEQUENCE_NAME = 'SEQ_TEST';

-- 잘못된 ALTER (ORA-04004 발생)
ALTER SEQUENCE seq_test
    MINVALUE 5000
    MAXVALUE 1000;  -- MINVALUE > MAXVALUE → 에러!

-- 올바른 ALTER SEQUENCE
ALTER SEQUENCE seq_test
    MINVALUE 1
    MAXVALUE 9999999999;  -- MINVALUE < MAXVALUE 조건 충족

-- 시퀀스 재시작이 필요한 경우 (Oracle 12c 이상)
ALTER SEQUENCE seq_test RESTART START WITH 1;

-- Oracle 11g 이하에서 시퀀스 재설정 방법
-- 기존 시퀀스 삭제 후 재생성
DROP SEQUENCE seq_test;

CREATE SEQUENCE seq_test
    START WITH 1
    INCREMENT BY 1
    MINVALUE 1
    MAXVALUE 9999999999
    NOCYCLE
    CACHE 20;

시퀀스 생성 전 유효성 검사 스크립트

-- 시퀀스 생성 전 MINVALUE와 MAXVALUE 유효성 체크
DECLARE
    v_minvalue NUMBER := 1;
    v_maxvalue NUMBER := 9999999;
    v_start    NUMBER := 1;
BEGIN
    IF v_minvalue >= v_maxvalue THEN
        RAISE_APPLICATION_ERROR(-20001,
            'MINVALUE(' || v_minvalue || ')는 MAXVALUE(' || v_maxvalue || ')보다 작아야 합니다.');
    END IF;

    IF v_start < v_minvalue OR v_start > v_maxvalue THEN
        RAISE_APPLICATION_ERROR(-20002,
            'START WITH 값은 MINVALUE와 MAXVALUE 사이에 있어야 합니다.');
    END IF;

    -- 유효성 통과 후 동적 SQL로 시퀀스 생성
    EXECUTE IMMEDIATE
        'CREATE SEQUENCE seq_validated ' ||
        'START WITH ' || v_start ||
        ' INCREMENT BY 1 ' ||
        ' MINVALUE ' || v_minvalue ||
        ' MAXVALUE ' || v_maxvalue ||
        ' NOCYCLE CACHE 20';

    DBMS_OUTPUT.PUT_LINE('시퀀스가 성공적으로 생성되었습니다.');
END;
/

예방 방법

  • 시퀀스 생성/변경 전 표준 템플릿 사용 및 코드 리뷰 의무화

모든 시퀀스 DDL 작업에 표준 템플릿을 마련하고, MINVALUE < MAXVALUE 조건을 체크리스트에 포함시켜야 합니다. 특히 대규모 마이그레이션이나 배포 작업 시에는 반드시 DBA 리뷰를 거쳐 실수를 사전에 방지해야 합니다. CI/CD 파이프라인에 시퀀스 DDL 유효성 검사 스크립트를 포함하는 것도 좋은 방법입니다.

  • USER_SEQUENCES 뷰를 활용한 정기적인 시퀀스 상태 모니터링

운영 중인 모든 시퀀스의 상태를 정기적으로 점검하는 모니터링 쿼리를 스케줄링하면 잠재적 문제를 미리 발견할 수 있습니다. 아래 쿼리를 주기적으로 실행하여 시퀀스의 잔여 범위가 부족해지는 시점을 사전에 감지하고 대응하는 것이 중요합니다.

-- 시퀀스 잔여 범위 모니터링 쿼리
SELECT SEQUENCE_NAME,
       MIN_VALUE,
       MAX_VALUE,
       LAST_NUMBER,
       MAX_VALUE - LAST_NUMBER AS REMAINING,
       ROUND((LAST_NUMBER - MIN_VALUE) / (MAX_VALUE - MIN_VALUE) * 100, 2) AS USED_PCT
FROM   USER_SEQUENCES
ORDER BY USED_PCT DESC;

관련 에러

  • ORA-04006: START WITH value을 위한 MINVALUE와 MAXVALUE 범위 초과 시 발생합니다.
  • ORA-04007: MINVALUE가 현재 시퀀스 값보다 클 때 발생합니다.
  • ORA-04008: MAXVALUE가 현재 시퀀스 값보다 작을 때 발생합니다.
  • ORA-04009: MAXVALUE를 지정하지 않고 NOMAXVALUE를 함께 사용하는 충돌 시 발생합니다.
  • ORA-02289: 존재하지 않는 시퀀스를 참조할 때 발생하는 에러로, 시퀀스 관련 작업에서 함께 접하는 경우가 많습니다.
DBMS 에러 코드 시리즈

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

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

댓글 남기기