日期字段未定义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,不论是从易用性,还是存储来看,都是最合适的。

近期更新的文章:

为何世界足坛历史射手王是C罗?

三种数据库架构的介绍

关于数据治理的读书笔记 - 数据治理路线图规划

Oracle优化器对谓词顺序处理的一个场景

究竟哪些语句是属于DDL?

文章分类和索引:

公众号900篇文章分类和索引

以上是关于日期字段未定义DATE类型所带来的一些问题的主要内容,如果未能解决你的问题,请参考以下文章

Graphql 日期字段类型必须是输出类型但得到:未定义

错误类型错误:无法读取未定义的属性“日期/时间”

MySQL的TIMESTAMP数据类型

MySQL的TIMESTAMP数据类型

DataTable:td内日期的自定义排序

Oracle中日期字段未定义日期类型的案例补充说明