2026년 08월 18일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-04002 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-04002 INCREMENT must be a nonzero integer 는?
ORA-04002 에러는 Oracle 시퀀스(Sequence) 객체를 생성하거나 변경할 때 INCREMENT BY 절에 0 또는 정수가 아닌 값을 지정할 경우 발생합니다. Oracle 시퀀스의 INCREMENT 값은 반드시 0이 아닌 양의 정수 또는 음의 정수여야 하며, 소수점이나 0을 허용하지 않습니다. 주로 CREATE SEQUENCE 또는 ALTER SEQUENCE 문을 작성할 때 잘못된 값을 입력하거나, 동적 SQL을 통해 시퀀스를 생성하는 배치 프로세스에서 변수 값이 잘못 전달될 때 자주 발생합니다.
주요 발생 원인
- INCREMENT BY 값에 0을 지정한 경우
가장 흔한 원인으로, 시퀀스의 INCREMENT BY 절에 명시적으로 0을 입력하는 경우입니다. Oracle 시퀀스는 각 호출 시마다 현재 값에서 INCREMENT 값만큼 증가 또는 감소해야 하는데, 0을 허용하면 시퀀스가 무한히 동일한 값을 반환하게 되어 논리적으로 불가능합니다. 이는 개발자가 시퀀스 스펙을 잘못 이해하거나 단순 오타로 인해 발생하는 경우가 많습니다.
- 소수점(실수) 값을 INCREMENT BY에 사용한 경우
INCREMENT BY 0.5 또는 INCREMENT BY 1.5처럼 정수가 아닌 실수 값을 지정하면 이 에러가 발생합니다. Oracle 시퀀스는 내부적으로 정수 기반으로 동작하도록 설계되어 있으며, 소수점 단위의 증가값은 지원하지 않습니다. 특히 외부 애플리케이션에서 시퀀스 생성 스크립트를 자동으로 생성하거나, 설정 파일에서 값을 읽어올 때 데이터 타입 변환 오류로 인해 발생할 수 있습니다.
- 동적 SQL 또는 스크립트에서 변수 바인딩 오류
PL/SQL이나 셸 스크립트에서 동적으로 시퀀스를 생성할 때, INCREMENT 값을 담은 변수가 NULL이거나 예상치 못한 값(빈 문자열, 0 등)으로 치환되는 경우 발생합니다. 자동화된 배포 스크립트나 CI/CD 파이프라인에서 환경 변수 값이 제대로 전달되지 않으면 런타임 시점에 이 에러가 터지기 때문에 운영 환경에서 더욱 치명적으로 작용할 수 있습니다.
해결 방법
원인 1: INCREMENT BY 0 지정 시 해결
0 대신 반드시 양수 또는 음수 정수를 사용해야 합니다. 아래와 같이 올바른 값으로 수정하세요.
-- 잘못된 예 (ORA-04002 발생)
CREATE SEQUENCE my_seq
START WITH 1
INCREMENT BY 0 -- 0은 허용되지 않음
NOCYCLE;
-- 올바른 예 (양의 정수)
CREATE SEQUENCE my_seq
START WITH 1
INCREMENT BY 1
MAXVALUE 999999999
NOCYCLE
CACHE 20;
-- 역방향 시퀀스 (음의 정수도 허용)
CREATE SEQUENCE my_seq_desc
START WITH 1000
INCREMENT BY -1
MINVALUE 1
NOCYCLE;
이미 생성된 시퀀스에서 INCREMENT 값이 잘못된 경우 ALTER SEQUENCE를 사용하여 수정합니다.
-- 기존 시퀀스 INCREMENT 값 수정
ALTER SEQUENCE my_seq INCREMENT BY 1;
-- 수정 후 현재 시퀀스 설정 확인
SELECT SEQUENCE_NAME, INCREMENT_BY, MIN_VALUE, MAX_VALUE, CYCLE_FLAG, CACHE_SIZE
FROM USER_SEQUENCES
WHERE SEQUENCE_NAME = 'MY_SEQ';
원인 2: 소수점 값 사용 시 해결
소수점 값은 반드시 정수로 변환하여 사용해야 합니다. 아래는 잘못된 예와 올바른 수정 예입니다.
-- 잘못된 예 (ORA-04002 발생)
CREATE SEQUENCE my_seq
START WITH 1
INCREMENT BY 0.5; -- 소수점 불가
-- 올바른 예: 소수점 대신 정수 사용
CREATE SEQUENCE my_seq
START WITH 1
INCREMENT BY 1;
-- 만약 10 단위로 증가가 필요하다면
CREATE SEQUENCE my_seq_by10
START WITH 10
INCREMENT BY 10
MAXVALUE 9999999990
NOCYCLE
CACHE 50;
원인 3: 동적 SQL 변수 바인딩 오류 해결
동적 SQL로 시퀀스를 생성할 때는 반드시 변수 값을 검증한 후 실행해야 합니다.
-- 안전하지 않은 동적 SQL (변수 검증 없음)
DECLARE
v_increment NUMBER := 0; -- 잘못된 값
v_sql VARCHAR2(500);
BEGIN
v_sql := 'CREATE SEQUENCE dyn_seq INCREMENT BY ' || v_increment;
EXECUTE IMMEDIATE v_sql; -- ORA-04002 발생
END;
/
-- 안전한 동적 SQL (변수 유효성 검사 포함)
DECLARE
v_increment NUMBER := 0; -- 외부에서 전달받은 값이라고 가정
v_sql VARCHAR2(500);
BEGIN
-- 유효성 검사: 0이거나 NULL이면 기본값 1로 대체
IF v_increment IS NULL OR v_increment = 0 THEN
RAISE_APPLICATION_ERROR(-20001, 'INCREMENT 값은 0이 아닌 정수여야 합니다.');
-- 또는 기본값으로 강제 설정
-- v_increment := 1;
END IF;
-- 소수점 여부 확인
IF v_increment != TRUNC(v_increment) THEN
RAISE_APPLICATION_ERROR(-20002, 'INCREMENT 값은 정수여야 합니다.');
END IF;
v_sql := 'CREATE SEQUENCE dyn_seq '
|| 'START WITH 1 '
|| 'INCREMENT BY ' || TO_CHAR(TRUNC(v_increment)) || ' '
|| 'NOCYCLE CACHE 20';
EXECUTE IMMEDIATE v_sql;
DBMS_OUTPUT.PUT_LINE('시퀀스 생성 완료: INCREMENT BY ' || v_increment);
END;
/
-- 생성 후 확인
SELECT SEQUENCE_NAME, INCREMENT_BY
FROM USER_SEQUENCES
WHERE SEQUENCE_NAME = 'DYN_SEQ';
예방 방법
- 시퀀스 생성 전 표준 템플릿 활용
조직 내에서 시퀀스 생성 시 검증된 표준 DDL 템플릿을 정의하고, 이를 반드시 사용하도록 개발 가이드라인에 명시하는 것이 중요합니다. 아래와 같은 표준 템플릿을 사용하면 INCREMENT BY 오류를 사전에 차단할 수 있습니다.
“`sql
— 표준 시퀀스 생성 템플릿 (팀 공용)
— [시퀀스명], [시작값], [증가값(0 제외 정수)] 을 명시적으로 지정
CREATE SEQUENCE [schema_name].[sequence_name]
START WITH [start_value] — 예: 1
INCREMENT BY [increment_value] — 예: 1 (반드시 0이 아닌 정수)
MINVALUE [min_value] — 예: 1
MAXVALUE [max_value] — 예: 9999999999999999999999999999
NOCYCLE
CACHE 20
NOORDER;
“`
- 동적 시퀀스 생성 시 공통 유틸리티 프로시저 사용
동적 SQL로 시퀀스를 생성해야 하는 경우, 반드시 입력값을 검증하는 공통 프로시저를 만들어 활용해야 합니다. 이를 통해 0값, NULL, 소수점 값이 INCREMENT BY에 전달되는 것을 원천 차단할 수 있으며, 에러 로깅 및 감사 추적도 함께 구현할 수 있습니다.
“`sql
CREATE OR REPLACE PROCEDURE create_sequence_safe(
p_seq_name IN VARCHAR2,
p_start IN NUMBER DEFAULT 1,
p_increment IN NUMBER DEFAULT 1,
p_cache IN NUMBER DEFAULT 20
) IS
v_sql VARCHAR2(1000);
BEGIN
— 유효성 검사
IF p_increment IS NULL OR p_increment = 0 THEN
RAISE_APPLICATION_ERROR(-20010, ‘[ERROR] INCREMENT 값은 0 또는 NULL이 될 수 없습니다.’);
END IF;
IF p_increment != TRUNC(p_increment) THEN
RAISE_APPLICATION_ERROR(-20011, ‘[ERROR] INCREMENT 값은 반드시 정수여야 합니다.’);
END IF;
— 시퀀스 생성
v_sql := ‘CREATE SEQUENCE ‘ || DBMS_ASSERT.SIMPLE_SQL_NAME(p_seq_name)
|| ‘ START WITH ‘ || TRUNC(p_start)
|| ‘ INCREMENT BY ‘ || TRUNC(p_increment)
|| ‘ NOCYCLE CACHE ‘ || TRUNC(p_cache);
EXECUTE IMMEDIATE v_sql;
DBMS_OUTPUT.PUT_LINE(‘시퀀스 [‘ || p_seq_name || ‘] 생성 완료.’);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(‘시퀀스 생성 실패: ‘ || SQLERRM);
RAISE;
END;
/
“`
관련 에러
- ORA-04001:
SEQUENCE옵션의 시작 값이 잘못된 경우 발생하는 에러로, ORA-04002와 유사하게 시퀀스 정의 오류 계열에 속합니다. - ORA-04003:
INCREMENT값이MAXVALUE와MINVALUE의 차이를 초과할 때 발생합니다. - ORA-04006:
START WITH값이MAXVALUE보다 큰 경우 발생하며, 시퀀스 범위 설정 오류입니다. - ORA-04007:
MINVALUE값이MAXVALUE보다 크거나 같을 때 발생하는 시퀀스 범위 충돌 에러입니다. - ORA-02289: 존재하지 않는 시퀀스를 참조할 때 발생하는 에러로, 시퀀스 관련 작업 시 함께 숙지해야 합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.