使用背景:公司有一個預存程序,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'------------------------------ 1SQL> SELECT FN_ISDATE(REPLACE('2015-05-32','-','')) FROM DUAL;FN_ISDATE(REPLACE('2015-05-32'------------------------------ 0SQL>
(2),在預存程序中使用:
CREATE OR REPLACE PROCEDURE ISBEGINIF 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; --日期類型的日期beginif 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;
歡迎大家提出更好的改進意見。