본문 바로가기
기술(technology)/Oracle

오라클(ORACLE) 날짜 유효성 체크 함수(function)

by shinPro 2021. 4. 30.
반응형

ORACLE 날짜 유효성 체크 함수


create or replace FUNCTION FNC."FN_CHK_DATE" (IN_STR IN VARCHAR2, IN_TYPE IN VARCHAR2)
    RETURN VARCHAR2
/******************************************************************************
   NAME:      FN_CHK_DATE
   PURPOSE:   날짜 유효성을 체크한다.
   REVISIONS:
   Ver        Date        Author           Description
   ---------  ----------  ---------------  ------------------------------------
   1.0        2021-04-30  신현준                                   1. Created this function.
   NOTES:
   파라미터 1(IN_STR)        :  체크할문자
   파라미터 2(IN_TYPE)        :  타입
******************************************************************************/ 
IS
    V_RETURN    VARCHAR2 (512);     -- 결과값
    V_STR       VARCHAR2 (512);     -- 입력값(날짜)
    V_YEAR      VARCHAR2 (4);       -- 입력값 내 년도
    V_LEAF      VARCHAR2 (1);       -- 입력값 윤년 여부
    V_REGEXP    VARCHAR2 (512);     -- 윤년 여부에 따른 정규식
    V_TYPE      VARCHAR2 (1);       -- 년월일 or 년월일시분초 타입
BEGIN
    -- 입력값 공백제거
    V_STR := TRIM(IN_STR);
    -- 년월일 or 년월일시분초 타입
    V_TYPE := IN_TYPE;
    
    IF  -- 빈값
        V_STR IS NULL OR V_STR = ''
    THEN
        V_RETURN := '';
    ELSIF   -- 숫자이외 값 확인
        REGEXP_INSTR(V_STR, '[^0-9]') != 0
    THEN
        V_RETURN := '';
    -- YYYYMMDD
    ELSIF
        V_TYPE = 'D'
    THEN
        IF      -- 자리수(년월일)
            LENGTH(V_STR) != 8
        THEN
            V_RETURN := '';
        ELSE   -- 날짜 및 윤년계산
            V_YEAR := SUBSTR(V_STR, 0, 4);
            CASE WHEN
                (MOD(V_YEAR, 4) = 0 AND MOD(V_YEAR, 100) != 0)
                OR
                (MOD(V_YEAR, 400) = 0)
            THEN
                V_LEAF := 'Y';
            ELSE
                V_LEAF := 'N';
            END CASE;
            
            IF
                V_LEAF = 'Y'
            THEN
                V_REGEXP := '^[0-9]{4}(((0[13578]|(10|12))(0[1-9]|[1-2][0-9]|3[0-1]))|(02(0[1-9]|[1-2][0-9]))|((0[469]|11)(0[1-9]|[1-2][0-9]|30)))$';
            ELSE
                V_REGEXP := '^[0-9]{4}(((0[13578]|(10|12))(0[1-9]|[1-2][0-9]|3[0-1]))|(02(0[1-9]|[1-2][0-8]))|((0[469]|11)(0[1-9]|[1-2][0-9]|30)))$';
            END IF;
            
            CASE WHEN
                NOT REGEXP_LIKE(V_STR, V_REGEXP)
            THEN
                V_RETURN := '';
            ELSE
                V_RETURN := V_STR;
            END CASE;
        END IF;
    -- YYYYMMDDHH24MISS
    ELSIF
        V_TYPE = 'T'
    THEN
        IF      -- 자리수(년월일시분초)
            LENGTH(V_STR) != 14
        THEN
            V_RETURN := '';
        ELSE   -- 날짜 및 윤년계산
            V_YEAR := SUBSTR(V_STR, 0, 4);
            CASE WHEN
                (MOD(V_YEAR, 4) = 0 AND MOD(V_YEAR, 100) != 0)
                OR
                (MOD(V_YEAR, 400) = 0)
            THEN
                V_LEAF := 'Y';
            ELSE
                V_LEAF := 'N';
            END CASE;
            
            IF
                V_LEAF = 'Y'
            THEN
                V_REGEXP := '^[0-9]{4}(((0[13578]|(10|12))(0[1-9]|[1-2][0-9]|3[0-1]))|(02(0[1-9]|[1-2][0-9]))|((0[469]|11)(0[1-9]|[1-2][0-9]|30)))(([0-1][0-9]|2[0-4])([0-5][0-9])([0-5][0-9]))$';
            ELSE
                V_REGEXP := '^[0-9]{4}(((0[13578]|(10|12))(0[1-9]|[1-2][0-9]|3[0-1]))|(02(0[1-9]|[1-2][0-8]))|((0[469]|11)(0[1-9]|[1-2][0-9]|30)))(([0-1][0-9]|2[0-4])([0-5][0-9])([0-5][0-9]))$';
            END IF;
            
            CASE WHEN
                NOT REGEXP_LIKE(V_STR, V_REGEXP)
            THEN
                V_RETURN := '';
            ELSE
                V_RETURN := V_STR;
            END CASE;
        END IF;
    END IF;
 
    RETURN V_RETURN;
EXCEPTION   -- 오류
    WHEN OTHERS
    THEN
        V_RETURN := 'ERR';
        RETURN V_RETURN;
END FN_ISERR_DATE;

 

반응형

댓글