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

ORA-01850
2026년 08월 04일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-01850 hour must be between 1 and 12 는?

ORA-01850 에러는 Oracle 데이터베이스에서 날짜/시간 형식 변환 시 12시간제(AM/PM) 형식인 HH 포맷 마스크를 사용할 때, 시(hour) 값이 1에서 12 범위를 벗어나는 경우 발생합니다. 예를 들어, TO_DATE, TO_TIMESTAMP 함수 등에서 HH 포맷을 사용하면서 0시, 13시, 또는 23시와 같이 12시간제로 표현할 수 없는 값을 입력하면 이 에러가 트리거됩니다. 특히 24시간 형식의 시간 데이터를 12시간 포맷으로 처리하려 할 때 실무에서 매우 빈번하게 발생하는 에러 중 하나입니다.


주요 발생 원인

  • HH 포맷 마스크 사용 시 24시간 형식 데이터 입력

가장 흔한 원인입니다. Oracle의 HH 포맷 마스크는 12시간제를 의미하므로, 1~12 사이의 값만 허용합니다. 애플리케이션이나 외부 시스템에서 24시간 형식(00~23)으로 넘어온 시간 데이터를 그대로 HH 포맷과 함께 사용할 경우 즉시 에러가 발생합니다. 예를 들어, 오전 0시를 의미하는 00이나 오후 2시를 의미하는 14HH 포맷으로는 처리 불가합니다.

  • HH12 포맷 마스크에서 시간 값 0(자정) 입력

HH12HH와 동일하게 12시간제를 나타내며, 1부터 12 사이의 값만 허용합니다. 일부 개발자들이 자정(midnight)을 표현하기 위해 00을 입력하거나, 낮 12시(정오)를 12가 아닌 0으로 처리하는 코드를 작성할 때 이 에러가 발생합니다. 12시간제에서 자정은 12:00:00 AM으로 표현되어야 하므로, 시 값이 반드시 1~12 범위 내에 있어야 합니다.

  • NLS 세션 설정 또는 암묵적 형식 변환(Implicit Conversion) 충돌

Oracle 세션의 NLS_DATE_FORMAT 파라미터가 HH를 포함하는 형식으로 설정되어 있을 때, 명시적 포맷 마스크 없이 문자열을 날짜로 변환하면 예상치 못한 ORA-01850 에러가 발생할 수 있습니다. 특히 다국어 환경이나 세션 설정이 서로 다른 배치 프로그램, 또는 레거시 코드에서 암묵적 형식 변환에 의존하는 경우 운영 환경에서 간헐적으로 이 에러가 나타나 원인 파악이 어려울 수 있습니다.


해결 방법

원인 1 해결: HHHH24로 변경

24시간 형식의 시간 데이터를 다루고 있다면, 포맷 마스크를 HH 대신 HH24로 변경하는 것이 가장 근본적인 해결책입니다.

-- 에러 발생 예시 (HH 포맷으로 14시 입력 시 ORA-01850 발생)
SELECT TO_DATE('2024-07-15 14:30:00', 'YYYY-MM-DD HH:MI:SS') FROM DUAL;
-- ORA-01850: hour must be between 1 and 12

-- 해결 방법: HH24 포맷 마스크 사용
SELECT TO_DATE('2024-07-15 14:30:00', 'YYYY-MM-DD HH24:MI:SS') FROM DUAL;
-- 정상 결과: 2024-07-15 14:30:00

-- TO_TIMESTAMP 에서도 동일하게 적용
SELECT TO_TIMESTAMP('2024-07-15 23:59:59', 'YYYY-MM-DD HH24:MI:SS') FROM DUAL;
-- 정상 결과: 2024-07-15 23:59:59.000000000

원인 2 해결: 12시간제 사용 시 AM/PM 명시

12시간제 포맷(HH 또는 HH12)을 반드시 사용해야 하는 경우에는 AM 또는 PM 포맷 요소를 함께 지정하고, 시 값이 1~12 범위 내에 있는지 확인해야 합니다.

-- 에러 발생 예시 (자정을 00으로 입력)
SELECT TO_DATE('2024-07-15 00:30:00 AM', 'YYYY-MM-DD HH:MI:SS AM') FROM DUAL;
-- ORA-01850: hour must be between 1 and 12

-- 해결 방법: 자정은 12로 표현해야 함
SELECT TO_DATE('2024-07-15 12:30:00 AM', 'YYYY-MM-DD HH:MI:SS AM') FROM DUAL;
-- 정상 결과: 2024-07-15 00:30:00 (자정 이후 30분)

-- 오후 2시 30분 표현
SELECT TO_DATE('2024-07-15 02:30:00 PM', 'YYYY-MM-DD HH:MI:SS AM') FROM DUAL;
-- 정상 결과: 2024-07-15 14:30:00

-- TO_TIMESTAMP 동일 적용
SELECT TO_TIMESTAMP('2024-07-15 11:59:59 PM', 'YYYY-MM-DD HH12:MI:SS AM') FROM DUAL;
-- 정상 결과: 2024-07-15 23:59:59.000000000

원인 3 해결: NLS_DATE_FORMAT 확인 및 명시적 포맷 지정

현재 세션의 NLS 설정을 확인하고, 항상 명시적 포맷 마스크를 사용하도록 코드를 수정합니다.

-- 현재 세션의 NLS_DATE_FORMAT 확인
SELECT VALUE 
FROM NLS_SESSION_PARAMETERS 
WHERE PARAMETER = 'NLS_DATE_FORMAT';

-- 세션 레벨에서 NLS_DATE_FORMAT을 안전한 24시간 형식으로 변경
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';

-- 데이터베이스 전체 NLS_DATE_FORMAT 확인
SELECT VALUE 
FROM NLS_DATABASE_PARAMETERS 
WHERE PARAMETER = 'NLS_DATE_FORMAT';

-- 암묵적 변환 방지: 항상 TO_DATE, TO_TIMESTAMP 함수에 포맷 명시
-- 나쁜 예 (암묵적 변환 - NLS 설정에 의존)
INSERT INTO orders (order_date) VALUES ('2024-07-15 14:00:00');

-- 좋은 예 (명시적 변환 - 포맷 마스크 직접 지정)
INSERT INTO orders (order_date) 
VALUES (TO_DATE('2024-07-15 14:00:00', 'YYYY-MM-DD HH24:MI:SS'));

-- 기존 데이터 조회 시 발생하는 경우 DUMP 함수로 확인
SELECT DUMP(order_date) FROM orders WHERE ROWNUM = 1;

추가: 혼합 데이터 처리 시 방어적 쿼리 작성

-- 외부에서 유입된 시간 문자열이 12시간제인지 24시간제인지 불분명할 때
-- CASE 문을 활용한 방어적 처리 예시
SELECT 
    time_str,
    CASE 
        WHEN REGEXP_LIKE(time_str, '(AM|PM)$', 'i') THEN
            TO_DATE(time_str, 'YYYY-MM-DD HH:MI:SS AM')
        ELSE
            TO_DATE(time_str, 'YYYY-MM-DD HH24:MI:SS')
    END AS converted_date
FROM (
    SELECT '2024-07-15 02:30:00 PM' AS time_str FROM DUAL
    UNION ALL
    SELECT '2024-07-15 14:30:00' AS time_str FROM DUAL
);

예방 방법

  • 항상 HH24 포맷 마스크를 기본 표준으로 사용하고, NLS 설정에 의존하지 말 것

개발 표준으로 TO_DATE, TO_TIMESTAMP 함수 사용 시 반드시 포맷 마스크를 명시적으로 지정하도록 코딩 가이드라인을 수립하세요. 24시간 시스템을 다루는 대부분의 엔터프라이즈 애플리케이션에서는 HH24를 기본 표준으로 채택하면 ORA-01850을 비롯한 다양한 날짜 관련 에러를 원천적으로 차단할 수 있습니다. 또한 코드 리뷰 단계에서 HH 포맷 단독 사용 여부를 체크리스트 항목으로 추가하는 것을 권장합니다.

  • 입력 데이터 유효성 검사(Validation) 및 데이터 계층에서의 정규화 처리

애플리케이션 레이어나 데이터베이스의 트리거, 제약 조건을 활용하여 시간 데이터가 Oracle에 저장되기 전에 유효성 검사를 수행하세요. 특히 외부 시스템 연동이나 배치 작업에서 유입되는 날짜/시간 데이터는 반드시 표준 포맷으로 정규화한 후 처리하도록 프로세스를 설계하고, CHECK 제약 조건이나 전용 변환 함수를 만들어 재사용하는 것이 좋습니다.


관련 에러

  • ORA-01849: hour must be between 1 and 12 와 유사하며, 분(minute)이 0~59 범위를 벗어날 때 발생하는 에러입니다.
  • ORA-01851: 분(minutes) 값이 0~59 범위를 벗어날 때 발생합니다.
  • ORA-01852: 초(seconds) 값이 0~59 범위를 벗어날 때 발생합니다.
  • ORA-01843: 유효하지 않은 월(month) 값이 입력될 때 발생하며, 날짜 포맷 불일치 시 자주 함께 나타납니다.
  • ORA-01830: 날짜 포맷 그림(picture)이 입력 문자열 변환 전에 종료될 때 발생하는 에러로, 포맷 마스크와 데이터 길이 불일치 시 나타납니다.
  • ORA-01858: 숫자가 있어야 할 위치에 숫자가 아닌 문자가 발견될 때 발생하며, ORA-01850과 함께 날짜 변환 오류의 대표적인 에러입니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기