暂无图片
暂无图片
7
暂无图片
暂无图片
暂无图片

Oracle日期列的相关问题

原创 冯睿 2022-03-16
2256

前文:

近期在某运营商驻场,期间处理了不少SQL相关的问题,发现大部分问题都与日期有关,接下来详细展开介绍。

正文:

1.SQL执行报错问题

有一天客户的开发向我反映,有一条SQL昨天还可以执行,今天就执行报错,需要帮忙排查一下。ORA-01843:not a valid month

select * from table where to_date(substr(crtTime, 0, 4) || '-' || substr(crtTime, 6, 2) || '-' ||
               substr(crtTime, 9, 2),
               'yyyy-mm-dd') = to_date('2022-03-01', 'yyyy-mm-dd'

crtTime列类型为varchar2,经过排查发现该列里面存的数据正常应该为‘yyyy-mm-dd’格式,但是有几条数据只是‘yyyy’所以导致to_date函数传入值只有yyyy,因此报错,以下为测试过程。

图1.png

由于这张表的crtTime列定义varchar2,因此在录入日期数据的时候,需要格外注意日期格式必须为yyyy-mm-dd,否则在使用to_date函数时可能会因为格式问题报错。

2.函数转换引发的SQL性能问题

接着说上个测试,由于在该列上还使用了函数(substr、to_date),会导致该列上的索引无法使用,只能使用全表扫描的访问路径,SQL执行效率低下。

图2.png

为了解决这个问题,在crtTime列不更改为date时,只能通过使用函数索引的方式来优化。

图3.png

3.排序问题

当记录日期的列类型为varchar2时,若使用数值记录的日期,仍然可以正常排序

图4.png

但是如果为英文日期类型,则无法按照日期排序,而是按照字符排序。

图5.png

4.非法日期问题

当记录日期的列数据类型为varchar2时,Oracle只会将数据认为是字符串而不会去校验日期,比如2022年的2月没有30号,4月是不会有31号的,这些不存在的日期将会被成功插入。

图7.png
图6.png

若列定义类型为date,在插入数据时Oracle会对日期进行校验,不会出现上述问题

图8.png

5.日期函数问题

在Oracle中有着一些处理日期的函数,比如add_mouths,last_day等等。在日期列类型为date时,使用起来非常方便。

图9.png

但是列类型为varchar2时,因为参数为字符,所以无法使用这类函数。

图10.png

6.存储字节长度问题

使用varchar2存储日期类型数据时,占用的空间要比date日期类型大,date类型固定占用7字节(世纪,年,月,日,时,分,秒)

图11.png图12.png

综上所述,在设计表的时候如果能够确认某列只使用日期,那么最好将列类型定义为date,不论是从易用性,还是存储来看都是非常好的。

最后修改时间:2022-03-16 16:13:38
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论