前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一个DATE数据类型的检索

一个DATE数据类型的检索

作者头像
bisal
发布2019-10-24 20:06:12
1.2K0
发布2019-10-24 20:06:12
举报

今天快下班时,兄弟团队过来问了个问题,一张表中的DATE类型字段在PLSQL-Developer中检索的时候,出现这种现象,如下所示,有记录存储的是"2019-01-01",即不带时间,有记录存储的是"2019-01-01 23:59:59",即带了时间,如果想找出所有这种不带时间的记录,并对其进行更新,应该如何操作?

640?wx_fmt=png
640?wx_fmt=png

首先,这存在个误区,有时候认为DATE类型存储的就是“日期”,TIMESTAMP类型存储的是“日期和时间”。在《SQL Language Reference》中对DATE数据类型进行了说明,明确指出DATE数据类型存储的是“date”日期和“time”时间,DATE数据类型都有自己的相关属性,对每个DATE类型的值,都会存储年、月、日、时、分和秒,换句话说,无论你是否指定,他都会存储这些,

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.

再说的明白点儿,DATE类型可以展示为"yyyy-mm-dd",也可以展示为"yyyy-mm-dd hh24:mi:ss",但是存储格式只有一种,即含时间的格式,"yyyy-mm-dd hh24:mi:ss"。

当指定存储“年月日”的日期时,他存储的是“年月日0点0分0秒”,在PLSQL Developer中,展示格式是"yyyy-mm-dd"(当然具体格式和Perferences的设置相关),即未带时间的。当指定存储“年月日时分秒”的日期时,他存储的是“年月日时分秒”,在PLSQL Developer中,展示格式是"yyyy-mm-dd hh24:mi:ss"(当然具体格式和Perferences的设置相关),即带时间的。

我们模拟下,

代码语言:javascript
复制
SQL> create table a (id number, cdate date);           
Table created.

SQL> insert into a values(1, to_date('2019-01-01','yyyy-mm-dd'));
1 row created.

SQL> insert into a values(1, to_date('2019-01-01 23:59:59','yyyy-mm-dd hh24:mi:ss'));
1 row created.

此时在PLSQL Developer中检索,能看到区别,

640?wx_fmt=png
640?wx_fmt=png

使用to_char转换,可以看到,第一条记录,其实时间是00:00:00,

640?wx_fmt=png
640?wx_fmt=png

下个问题,就是如何找到,这些所谓不带时间的记录,一开始是想通过extract函数,提取出“时分秒”,让其分别等于0,作为条件检索,

640?wx_fmt=png
640?wx_fmt=png

但实际执行,提示错误ORA-00920,即无效的关系运算符,

代码语言:javascript
复制
SQL> select * from a where extract(hour from cdate)=00 and extract(minute from cdate)=00
  2  and extract(second from cdate);
and extract(second from cdate)
                             *
ERROR at line 2:
ORA-00920: invalid relational operator

看下extract的介绍,已经说了,如果需要HOUR、MINUTE或者SECOND,需要extract参数必须是TIMESTAMP, TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE, or INTERVAL DAY TO SECOND,不能是DATE,因为Oracle会将DATE看做是ANSI的DATE数据类型,他是不包含时间字段的,

If HOUR, MINUTE, or SECOND is requested, then expr must evaluate to an expression of data type TIMESTAMP, TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE, or INTERVAL DAY TO SECOND. DATE is not valid here, because Oracle Database treats it as ANSI DATE data type, which has no time fields.

既然我要找的,是时间为00:00:00的,通过to_char,指定"hh24:mi:ss"的格式,进行检索,是可以找到的,

代码语言:javascript
复制
SQL> select * from a WHERE to_char(cdate, 'hh24:mi:ss')='00:00:00';
        ID CDATE
---------- ----------
         1 2019-01-01

如果需要将其更新为23:59:59,就这么做,

代码语言:javascript
复制
SQL> UPDATE a SET cdate=cdate+(1-1/86400) WHERE to_char(cdate, 'hh24:mi:ss')='00:00:00';
1 row updated.

当然,如上只是测试,生产环境中,若数据量很大,需要在where中增加合适的条件,避免全表扫描,尤其是更新操作。

这个问题不复杂,但你要明白DATE数据类型的实际存储,进而找到如何检索记录的线路,另外,像extract这种的函数,Oracle中还有很多,一些不常用的,并不需要背下来,当需要的时候,你能找到语法,知道如何使用,就可以了。

我上面使用to_char的解决方案,可能只是其中一种方式,如果各位有更好的解决方案,欢迎提出来,共同学习。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-10-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档