mysql jdbc处理0日期格式蛋疼问题-也算是BUG

最近在写一个数据库访问的中间平台时,使用MySQL JDBC处理一些日期数据,遇到点变态的问题,给大家乐一乐!

首先来看看什么样的日期数据这么蛋疼呢?

DATE            0000-00-00

DATETIME   0000-00-00 00:00:00

TIMESTAMP 0000-00-00 00:00:00

TIME               25:21:22

对于前3种情况,直接用JDBC读取,肯定会报错,报错信息类似这样:

Value ‘0000-00-00‘ can not be represented as java.sql.Date

或者

Value ‘0000-00-00‘ can not be represented as java.sql.Timestamp

为什么?日期值即使是0,也对应到1970-01-01,这种变态的日期格式,不知道那个奇人想出来的。

对于这样的问题,很多小伙伴想到的第一种办法就是在jdbc url参数上设置一个:zeroDateTimeBehavior=convertToNull

便可以让Java程序不报错了!因为JDBC内部发现是0日期格式,则会转换为null返回。

验证中确实可以解决问题,但是,但是,某个用户的数据库就是写入了这样的一条数据,但是程序确返回了null,用户认为这并不是他想要的数据(例如在做数据迁移时,目标字段不可空,此时就会报错),用户就希望看到的是0000-00-00这样格式的数据。怎么办呢?

首先必须是将参数zeroDateTimeBehavior=convertToNull去掉,否则程序拿到的始终是null,根本不知道数据库的数据是什么。但是这样程序会报错,不论用getString还是getObject都会报错。

经过验证,发现getBytes()不会报错,然后通过得到的bytes[]数组,new String(bytes[])就可以得到一个这样的字符串,并且与数据库内一致。似乎问题解决了?

没有,更蛋疼的问题出现了,当JDBC启用流模式或游标模式时,getBytes()也会报同样的错误,经过验证发现get各种类型都会报错,这尼玛太蛋疼了,没空看源码,据我估计,MySQL JDBC在流模式和游标模式中,对结果集的某些类型转换处理,没有复用普通模式(默认是本能地静态数据)的处理代码导致了这样的问题。

但是对于某些大数据的处理,业务应用中必须启用流模式或游标模式,因此陷入了一个死套--因此我认为这是MySQL JDBC的一个BUG。

但是用户的问题必须要解决,为此,不得不去用一下特殊的处理方式,异常判定,我想你看到这里应该认为这是世界上最土的办法了,呵呵!也就是捕获上面描述的Message信息,若发现则认为是0日期格式来解决,准备提交官方BUG,希望尽快能修复吧。

最后来说说Time类型,MySQL这个蛋疼的Time类型是指时长,而不是指日期上的小时:分钟:秒,因此它的小时数是可以超过24的,但是这样的值让Java来解析就会报错,因此对于MySQL的Time类型处理的时候未了避免问题。通常用getBytes()方式来获取值,然后用new String(byte[])来得到具体值,当然先要判空。

mysql jdbc处理0日期格式蛋疼问题-也算是BUG

时间: 2024-07-31 13:57:25

mysql jdbc处理0日期格式蛋疼问题-也算是BUG的相关文章

MySQL如何导出带日期格式的文件

一网友问在MySQL中如何只用SQL语句导出带日期格式的文件.觉得有点意思,于是尝试了一下.导出文件使用SELECT INTO OUTFILE 但是OUTFILE后面的值不能使用变量,所以只能使用动态SQL语句来实现.其中表user为测试表.具体语句如下所示 mysql> SET @SqlScript= CONCAT("SELECT * INTO OUTFILE '/tmp/sql_out_", DATE_FORMAT(NOW(), '%Y%m%d%H%i%s'), "

使用node查询数据库(mysql)时,日期格式不对的问题。

https://blog.csdn.net/chanlingmai5374/article/details/93190983 1.问题场景 数据库里存了 datetime.但 Node 查询出来是这样子的: 2019-05-14T21:40:59.000Z 2.解决办法 这是 Mysql时区 与 Node时区 不一致导致的.解决方法:配置Node数据库连接.加上 timezone 这一行: client: { host: '***.***.***.***', port: '****', user

MySql和Oracle的日期转换到底有哪些不同?我们来比较一下

1.MySql和Oracle的日期转换 mysql中有2种日期格式DATE和TIME,oracle只有一种日期格式DATE. oracle> select to_char(sysdate,'yyyy-mm-dd') from dual; oracle> select to_char(sysdate,'hh24-mi-ss') from dual; mysql> select date_format(now(),'%Y-%m-%d'); mysql> select time_form

关于MySQL中使用LOAD DATA INFILE导入csv文件时的日期格式问题

在使用MySQL时,常常会用到Load Data Infile来导入数据,在遇到Date类型的列时,有时会遇到格式转换的问题: 首先创建一张简单的people表,包含名字,生日,年龄三个字段: mysql> create table people( -> name varchar(10) NOT NULL, -> birthday date NOT NULL, -> age int NOT NULL); Query OK, 0 rows affected (0.18 sec) 构造

mysql JDBC URL格式

mysql JDBC URL格式如下: jdbc:mysql://[host:port],[host:port].../[database][?参数名1][=参数值1][&参数名2][=参数值2]... 现只列举几个重要的参数,如下表所示: 参数名称 参数说明 缺省值 最低版本要求 user 数据库用户名(用于连接数据库)   所有版本 password 用户密码(用于连接数据库)   所有版本 useUnicode 是否使用Unicode字符集,如果参数characterEncoding设置为

ISO日期格式标准,浏览器到服务器到mysql中的时区

时区简单理解 https://zh.wikipedia.org/wiki/%E6%97%B6%E5%8C%BA 上面的链接是时区的wiki说明,下面说说我记住的部分: GMT时区是格林威治标准时间,我把它理解为 “真实时间” UTC时区是根据GMT得来的“世界标准时间”,它的时间和GMT是相同的 CST可以指下列的时区: 澳洲中部时间,Central Standard Time (Australia)中部标准时区(北美洲),Central Standard Time (North America

mysql select日期格式

mysql表中datatime类型存储为2016-01-10,C#直接select 后,在datatable里面看,变成01/10/2016,需要还原回去,使用select DATE_FORMAT(列名,'%Y-%m-%d')即可 附上 mySQL中常用日期时间函数: 下面的查询选择了所有记录,其date_col的值是在最后30天以内: mysql> SELECT something FROM table WHERE TO_DAYS(NOW()) - TO_DAYS(date_col)<= 3

mysql JDBC URL格式各个参数详解

mysql JDBC URL格式各个参数详解 mysql JDBC URL格式如下: jdbc:mysql://[host:port],[host:port].../[database][?参数名1][=参数值1][&参数名2][=参数值2]... 现只列举几个重要的参数,如下表所示: 参数名称 参数说明 缺省值 最低版本要求 user 数据库用户名(用于连接数据库)   所有版本 password 用户密码(用于连接数据库)   所有版本 useUnicode 是否使用Unicode字符集,如

mysql 中的日期格式。date_format( ) 转换格式

date_format( ) 转换格式 : 格式 描述 %a 缩写星期名 %b 缩写月名 %c 月,数值 %D 带有英文前缀的月中的天 %d 月的天,数值(00-31) %e 月的天,数值(0-31) %f 微秒 %H 小时 (00-23) %h 小时 (01-12) %I 小时 (01-12) %i 分钟,数值(00-59) %j 年的天 (001-366) %k 小时 (0-23) %l 小时 (1-12) %M 月名 %m 月,数值(00-12) %p AM 或 PM %r 时间,12-小