Incorrect datetime value ‘2021-02‘ for function str_to_date

在使用MySQL的STR_TO_DATE函数将字符串转换成Date类型的时候,会出现类似:Incorrect datetime value '2021-02' for function str_to_date的错误。下面来看看解决办法。

 

情景复现:

(1)创建表:

create table time_table(
`year` varchar(4),
`month` varchar(2),
`day` varchar(2)
);

(2)插入数据:

INSERT INTO time_table
(`year`, `month`, `day`)
VALUES('2021', '03', '02');

(3)查询数据:

select STR_TO_DATE(CONCAT(`year`,'-',`month`),'%Y-%m') from time_table;

执行语句不发生错误,但返回的结果为NULL:

(4)更新数据:

update time_table set month = '04' where  STR_TO_DATE(CONCAT(`year`,'-',`month`),'%Y-%m') > CURRENT_DATE();

执行更新语句产生错误:Incorrect datetime value: '2021-03' for function str_to_date

问题原因:

产生Incorrect datetime value: '2021-03' for function str_to_date报错的原因是对STR_TO_DATE函数的使用不当。STR_TO_DATE(参数1, 参数2),其中参数1必须是年月日格式的字符串,比如:'2021-03-02'。因为CONCAT(`year`,'-',`month`)语句得到的字符串只含有年月,缺少了日,不是正确的年月日格式,因此会提示错误。对于参数2是日期格式,形式必须和参数1保持一致,即如果参数1为'2021-03-02',那么参数2需要为'%Y-%m-%d'。如果参数1为'2021/03/02',那么参数2需要为'%Y/%m/%d'。

 参数1和参数2格式必须一致,该特点和Java中的SimpleDateFormat特点一致,比如:

// 对应STR_TO_DATE的参数2
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-mm");
// 对应STR_TO_DATE的参数1
Date date = simpleDateFormat.parse("2021/03/02");
System.out.println(date);

运行该代码,会报错:

Exception in thread "main" java.text.ParseException: Unparseable date: "2021/03/02"

(1)比如如下参数1(使用斜杠分割)和参数2(使用短杠分割)格式不一致,查询语句结果为NULL:

更新语句报错:

(2)再比如如下参数1是年月日格式,参数2是年月表达式,查询语句仍然返回NULL:

更新语句报错:

(3)比如如下查询语句,参数1和参数2格式一致,都可以返回结果:

select STR_TO_DATE(CONCAT(`year`,'-',`month`, '-', `day`),'%Y-%m-%d') from time_table;
select STR_TO_DATE(CONCAT(`year`,'/',`month`, '/', `day`),'%Y/%m/%d') from time_table;

如下更新语句都可以正常执行,不提示错误:

update time_table set month = '04' where  STR_TO_DATE(CONCAT(`year`,'-',`month`, '-', `day`),'%Y-%m-%d') > CURRENT_DATE();
update time_table set month = '04' where  STR_TO_DATE(CONCAT(`year`,'/',`month`, '/', `day`),'%Y/%m/%d') > CURRENT_DATE();

解决办法:

如果一定要使用STR_TO_DATE(CONCAT(`year`,'-',`month`),'%Y-%m')这样的格式,也是有解决办法的。

(1)查看SQL_MODE

select @@SQL_MODE

会在返回结果中看见有个内容:NO_ZERO_DATE

出现上述报错的原因,就是这个模式的作用结果。我们可以将该模式移除,便可以解决报错问题。

(2)移除NO_ZERO_DATE

SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'NO_ZERO_DATE', '');

将SQL_MODE中的NO_ZERO_DATE内容替换成空字符串,即可将模式移除。

(3)再执行前面的UPDATE语句

语句顺利执行,并且数据也被改变。

(4)再执行前面的SELECT语句

返回值不再是NULL,而是有内容了。但是内容除了年月,还包含了日,而且日期是2021-04(经过UPDATE语句修改后的数据库值)的前一个月的最后一天。

 

SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'NO_ZERO_DATE', '');

该语句移除NO_ZERO_DATE模式,仅仅在当前会话内有效。当你断开当前的数据库连接,再重新连接,此时该模式恢复,执行UPDATE语句仍然会报错。

全局修改的方式是添加GLOBAL,这样修改的方式在断开重新连接以后,修改仍然有效。但是如果重启MySQL服务之后就会恢复到原先的设置。

SET GLOBAL SQL_MODE = REPLACE(@@SQL_MODE, 'NO_ZERO_DATE', '');

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值