热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

为什么日期不建议使用VARCHAR2或者NUMBER?

为什么日期不建议使用VARCHAR

通常在数据库表设计时,不建议将日期类型的字段定义为VARCHAR2或者NUMBER类型,语义是其中一方面的原因,从使用层面,还是有其他原因。

若定义为VARCHAR2类型,模拟如下,

    SQL> create table test(c1 varchar2(25));
    Table created.

    插入三条数据,

      SQL> insert all into test(c1) values('01JAN21')
      2 into test(c1) values('01APR21')
      3 into test(c1) values('01MAR21')
        4  select 1 from dual;
      3 rows created.

      如下结果的顺序是随机的,

        SQL> select * from test;
        C1
        -------------------------
        01JAN21
        01APR21
        01MAR21

        P.S. 可参考《Oracle数据顺序问题》、《Oracle读取数据的顺序问题》。

        如果我需要按照日期递增顺序返回,仅仅通过order by,得到的结果如下,明显是错误的,因为字段c1是字符串类型,order by排序的时候是按照字母的顺序,

          SQL> select * from test order by c1;
          C1
          -------------------------
          01APR21
          01JAN21
          01MAR21

          如果按照实际日期的顺序,则可以在order by中进行显式地转换,他是按照日期类型排序的,

            SQL> select * from test order by to_date(c1, 'DDMONYY');
            C1
            -------------------------
            01JAN21
            01MAR21
            01APR21

            因此我们说对日期类型,如果按照字符串类型存储,像排序这种操作,需要进行转换,才可以得到正确的结果,在程序中需要注意的。

            如果将日期存储为数值NUMBER类型,重复如上操作,是可以得到正确的结果,因为数值类型的排序从语义上和日期排序是相同的,

              SQL> create table test(c1 number);
              Table created.

              SQL> insert all into test(c1) values(20210101)
              2 into test(c1) values(20210401)
              3 into test(c1) values(20210301)
                4  select 1 from dual;
              3 rows created.

              SQL> select * from test;
              C1
              ----------
              20210101
              20210401
              20210301

              SQL> select * from test order by c1;
              C1
              ----------
              20210101
              20210301
              20210401

              但是一些将日期作为参数的函数,就无法直接使用,

                SQL> select c1, add_months(c1,1) from test;
                select c1, add_months(c1,1) from test
                *
                ERROR at line 1:
                ORA-00932: inconsistent datatypes: expected DATE got NUMBER

                需要显式转换,

                  SQL> select c1, add_months(to_date(c1,'yyyy-mm-dd'),1) c from test;      
                  C1 C
                  ---------- ------------------
                  20210101 01-FEB-21
                  20210401 01-MAY-21
                  20210301 01-APR-21

                  虽然这种函数消耗在当前的软硬件环境中,几乎就是忽略不计的,但是从严谨性、精算性、规范性的角度,还是应当避免这种情况,既然数据库给我们提供了DATE、TIMESTAMP等数据类型,为的就是存储日期类型,除非有特殊用途,建议还是按照语义使用正确的数据类型存储,至少不会错,否则就需要充分考虑不对称的数据类型需要在程序中进行什么转换,才可以确保正确。

                  近期更新的文章:

                  《》

                  《写代码如何事半功倍?》

                  《支持超过4000字节的varchar2类型》

                  《“自以为对的”MyBatis空闲连接探测的机制》

                  《小白学习MySQL - 索引键长度限制的问题》

                  《积累一些SQL》

                  《创建主键的三种方式对指定索引表空间操作的纠正》

                  《Oracle优化器的“短路”》

                  小白学习MySQL - MySQL会不会受到“高水位”的影响?

                  《MySQL行转列的小需求》

                  《Oracle的greatest和least函数》

                  《我的股市生涯》

                  《Oracle创建主键的三种方式》

                  《非Oracle Linux下Oracle 19c CDB数据库安装》

                  《案例纠正一则》

                  《小白学习MySQL - 数据库软件和初始化安装》

                  《小白学习MySQL - 闲聊聊》

                  《Redis和Sentinel的安装部署和配置》

                  “火线”和“零线”

                  《通过索引提升SQL性能案例一则》

                  《如何手动添加jar包到maven本地库?》

                  《1元股权转让的一点思考》

                  《如何打造一个经常宕机的业务系统?》

                  《Linux恢复误删文件的操作》

                  《Linux的scp指令使用场景》

                  《Oracle处理IN的几种方式》

                  《如何搭建一支拖垮公司的技术团队?》

                  《IP地址解析的规则》

                  《MySQL的skip-grant-tables》

                  《国产数据库不平凡的一年》

                  《Oracle要求顺序的top数据检索问题》

                  《日常工作中碰到的几个技术问题》

                  《了解一下sqlhc》

                  《Oracle的MD5函数介绍》

                  《Oracle 19c的examples静默安装》

                  《sqlplus登录缓慢的解决》

                  《VMWare 11安装RedHat Linux 7过程中碰到的坑》

                  《COST值相同?是真是假?》

                  《Oracle 11g的examples静默安装》


                  文章分类和索引:

                  《公众号700篇文章分类和索引》



                  推荐阅读
                  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
                  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
                  • Python SQLAlchemy库的使用方法详解
                    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
                  • Java String与StringBuffer的区别及其应用场景
                    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
                  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
                  • 如何在php中将mysql查询结果赋值给变量
                    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
                  • MyBatis多表查询与动态SQL使用
                    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
                  • Oracle优化新常态的五大禁止及其性能隐患
                    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
                  • 本文主要复习了数据库的一些知识点,包括环境变量设置、表之间的引用关系等。同时介绍了一些常用的数据库命令及其使用方法,如创建数据库、查看已存在的数据库、切换数据库、创建表等操作。通过本文的学习,可以加深对数据库的理解和应用能力。 ... [详细]
                  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
                  • Spring特性实现接口多类的动态调用详解
                    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
                  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
                  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
                  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
                  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
                  author-avatar
                  Ada乐悠悠
                  这个家伙很懒,什么也没留下!
                  PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
                  Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有