• Oracle日期校验函数


    使用背景:公司有一个存储过程。insert 总是不成功,之后debug,看到insert语句中有对日期处理的函数,
    TO_CHAR (TO_DATE (v_slot_date, 'yyyy-mm-dd'),'yyyy-mm')
    查看跳出进入exception时的v_slot_date值,发现v_slot_date是'2013.12月'。才恍然大悟,原来是传入的
    日期字符串不规范,所以导致inset出现异常。

    所以就准备些一个函数来推断录入日期的正确性。

    1,。怎样使用本函数
    (1), 在SQL语句中使用:

    SQL> SELECT FN_ISDATE(REPLACE('2015-05-12','-','')) FROM DUAL;
    FN_ISDATE(REPLACE('2015-05-12'
    ------------------------------
                                 1
    
    SQL> SELECT FN_ISDATE(REPLACE('2015-05-32','-','')) FROM DUAL;
    FN_ISDATE(REPLACE('2015-05-32'
    ------------------------------
                                 0
    
    SQL> 

    (2),在存储过程中使用:
    CREATE OR REPLACE PROCEDURE 
    IS
    BEGIN
    	IF FN_ISDATE(slotDate)=1
    	    THEN
    	    INSERT INTO PESK.R_HR_SLOT(....)VALUES(......);
    	    COMMIT;
    	END IF;
    END
    

    2。存储函数内容例如以下:

    create or replace function FN_ISDATE
    (
        v_datestr VARCHAR2  --日期入參
    )
    return number -- 返回1为正确。0为错误。
    as
    /*------------------------------------------------------------------------
     公用函数:日期检查函数
     调用范例: select FN_ISDATE('20140501') from dual;
    ------------------------------------------------------------------------*/
        i_year  number; --年
        i_month number; --月
        i_day   number; --日
        d_tjrq  date;   --日期类型的日期
    begin
    
    
    
    
    if v_datestr is null then
      return 0;
    end if;
    
    
    if length(trim(v_datestr)) <> 10 then
      return 0;
    end if;
    
    
    -- 推断日期由数字组成
    if regexp_substr(trim(v_datestr),'[[:digit:]]+') is null then
      return 0;
    end if;
    
    
    
    
    -- 截取出年份
    i_year:=to_number(substr(rtrim(v_datestr),1,4));
    
    
    -- 截取出月份
    i_month:=to_number(substr(rtrim(v_datestr),6,2));
    
    
    -- 截取出日期
    i_day:=to_number(substr(rtrim(v_datestr),9,2));
    
    
    -- 对月份进行推断。必须在1月到12月范围之内
    if i_month not between 1 and 12 then
        begin
            return 0;
        end;
    end if;
    
    
    -- 对日期的推断,1。3。5,7,8,10。12月最大日为31。4。6。9。11月最大日为30,2月若为闰年则为29。其他年则为28.
    if i_day between 1 and 31 then
        begin
            if i_day=31 and i_month not in (1,3,5,7,8,10,12) then
                begin
                    return 0;
                end;
            end if;
            if i_month=2 then
                begin
        -- Rules 1:普通年能被4整除且不能被100整除的为闰年。

    -- Rules 2:世纪年能被400整除的是闰年。 -- Rules 3:对于数值非常大的年份,这年假设能整除3200,而且能整除172800则是闰年。

    如172800年是闰年,86400年不是闰年。

    if ((mod(i_year,4)=0 and mod(i_year,100)<>0) or mod(i_year,400)=0 or (mod(i_year,3200)=0 and mod(i_year,172800)=0)) then begin --若为闰年。则2月份最大日为29 if i_day>29 then begin return 0; end; end if; end; else begin --若不为闰年,则2月份最大日为28 if i_day>28 then begin return 0; end; end if; end ; end if; end; end if; return 1; end; else return 0; end if; end;


    欢迎大家提出更好的改进意见。


  • 相关阅读:
    seajs模块化开发
    agularJs 路由
    sass
    web工作流
    lufylegend游戏引擎
    canvas游戏之贪食蛇
    [bzoj3743 Coci2015] Kamp(树形dp)
    [bzoj2662 BeiJing wc2012] 冻结 (分层图+最短路)
    [luogu2680] 运输计划 (lca+二分+树上差分)
    [luogu1463 HAOI2007] 反素数 (约数)
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10802997.html
Copyright © 2020-2023  润新知