日期字段未定义DATE类型所带来的一些问题
Posted bisal(Chen Liu)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了日期字段未定义DATE类型所带来的一些问题相关的知识,希望对你有一定的参考价值。
关于日期字段定义为非DATE类型,之前文章《为什么日期不建议使用VARCHAR2或者NUMBER?》做了一些介绍,碰巧看到这个贴子做了更全面的说明。
原文链接,https://www.modb.pro/db/376730
Oracle日期列相关的一些问题,如下所示。
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,因此报错,以下为测试过程,
由于这张表的crtTime列定义varchar2,因此在录入日期数据的时候,需要格外注意日期格式必须为yyyy-mm-dd,否则在使用to_date函数时可能会因为格式问题报错。
2. 函数转换引发的SQL性能问题
接着说上个测试,由于在该列上还使用了函数(substr、to_date),会导致该列上的索引无法使用,只能使用全表扫描的访问路径,SQL执行效率低下,
为了解决这个问题,在crtTime列不更改为date时,只能通过使用函数索引的方式来优化,
3. 排序问题
当记录日期的列类型为varchar2时,若使用数值记录的日期,仍然可以正常排序,
但是如果为英文日期类型,则无法按照日期排序,而是按照字符排序,
4. 非法日期问题
当记录日期的列数据类型为varchar2时,Oracle只会将数据认为是字符串而不会去校验日期,比如2022年的2月没有30号,4月是不会有31号的,这些不存在的日期将会被成功插入,
如下所示,
若列定义类型为date,在插入数据时Oracle会对日期进行校验,不会出现上述问题,
5. 日期函数问题
在Oracle中有着一些处理日期的函数,比如add_mouths、last_day等等。在日期列类型为date时,使用起来非常方便,
但是列类型为varchar2时,因为参数为字符,所以就无法使用这类函数,
6. 存储字节长度问题
使用varchar2存储日期类型数据时,占用的空间要比date日期类型大,date类型固定占用7字节(世纪,年,月,日,时,分,秒),
因此,设计表的时候如果能够确认某列只使用日期,那么最好将列类型定义为date,不论是从易用性,还是存储来看,都是最合适的。
近期更新的文章:
文章分类和索引:
以上是关于日期字段未定义DATE类型所带来的一些问题的主要内容,如果未能解决你的问题,请参考以下文章