DATE类型的“小陷阱”

浪尽此生 提交于 2021-02-12 19:04:02

朋友提了个问题,虽然不是难题,但确实很细微,很可能就掉进了陷阱中,假设执行日期是2020-08-26,创建测试数据,

SQL> create table t01 (id number, insert_time date); Table created.
SQL> insert into t01 values(1, to_date('2020-08-25','yyyy-mm-dd'));1 row created.


需求是检索insert_time是昨天的记录,他用这条SQL,通过trunc(sysdate)-1得到前一天的日期作为条件,乍看很合理,但是结果是0,

SQL> select * from t01 where insert_time > trunc(sysdate)-1;no rows selected


但是他使用trunc(sysdate)-2,能得到记录,“-2”不是前天?不是昨天啊?

SQL> select * from t01 where insert_time > trunc(sysdate)-2;        ID INSERT_TIME---------- ------------------         1 25-AUG-20


其实这个问题很简单,DATE类型在Oracle中定义包含了“年、月、日、时、分、秒”,即使像上例中,to_date('2020-08-25','yyyy-mm-dd'),只是指定年月日,还是包括时分秒,默认值是0,

DATE Data Type
The DATE data type stores date and time information. Although date and time information can be represented in both character and number data types, the DATE data type has special associated properties. For each DATE value, Oracle stores the following information: year, month, day, hour, minute, and second.


The default date values are determined as follows:
The year is the current year, as returned by SYSDATE.
The month is the current month, as returned by SYSDATE.
The day is 01 (the first day of the month).
The hour, minute, and second are all 0.


trunc(sysdate)-1是指"昨天00:00:00",如下SQL,能证明,

SQL> select to_char(trunc(sysdate),'yyyy-mm-dd hh24:mi:ss') from dual;TO_CHAR(TRUNC(SYSDA-------------------2020-08-26 00:00:00


条件中的>trunc(sysdate)-1,就是超过昨天00:00:00的,而存储的数据,to_date('2020-08-25','yyyy-mm-dd'),就是昨天00:00:00,因此无结果,这是正常的,需要用insert_time > trunc(sysdate)-2,才可以找到。


但如果插入时就指定了时分秒,就会不同了,

SQL> insert into t01 values(1, to_date('2020-08-25 01:00:00','yyyy-mm-dd hh24:mi:ss'));1 row created.


是可以找到的,

SQL> select * from t01 where insert_time > trunc(sysdate)-1;        ID INSERT_TIME---------- ------------------         1 25-AUG-20


格式化下,会更清楚些,的确是找到了01:00:00的,

SQL> select id, to_char(insert_time,  'yyyy-mm-dd hh24:mi:ss'from t01 where insert_time > trunc(sysdate)-1;        ID TO_CHAR(INSERT_TIME---------- -------------------         1 2020-08-25 01:00:00


这个问题,虽然细微,但稍不注意,可能在写程序时,就会忽视,造成边界值隐患,因此,还是要关注下。



近期的热文:

SQL工具集-格式化结果的SQL

SQL工具集-查询会话等待

数据库到底能不能部署在docker容器中?

一道SQL问题,你来试试的?

如何捕获问题SQL解决过度CPU消耗的问题

如何查看JVM运行的堆内存情况

Linux下如何快速删除大量碎小的文件?

打造国产技术产品的必要性

Oracle删除字段的方式和风险,你都了解么?

登录缓慢的诡异问题

PLSQL Developer几个可能的隐患

从70万字SRE神作提炼出的7千字精华文章

从数据误删到全量恢复的惊险记录

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

本文分享自微信公众号 - bisal的个人杂货铺(gh_e8769c7350b1)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!