设为首页 收藏本站
查看: 991|回复: 0

[经验分享] Oracle日期校验函数

[复制链接]

尚未签到

发表于 2016-7-21 08:45:26 | 显示全部楼层 |阅读模式
使用背景:公司有一个存储过程,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;

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

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-247123-1-1.html 上篇帖子: ora-00054,oracle锁表问题 下篇帖子: Oracle 删除所有session
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表