MySQL 8.0中DAY()函数查询正常但插入数据时报错的原因是什么
问题原因分析
- SQL模式的校验规则差异
MySQL 8.0默认开启了STRICT_TRANS_TABLES严格SQL模式,该模式对查询操作和DML操作的非法值处理逻辑完全不同:- 执行SELECT查询时,日期隐式转换失败仅会触发警告,
DAY()函数接收到非法日期值'20210832'时会返回NULL,后续可以正常执行IF分支判断,返回替换后的结果,不会中断查询。你执行SELECT语句时看到的1 warning就是转换失败的提示。 - 执行INSERT这类DML操作时,严格模式下只要出现非法值的隐式转换,就会直接抛出错误终止执行,不会继续走后续的业务逻辑。
- 执行SELECT查询时,日期隐式转换失败仅会触发警告,
- 执行顺序的影响
IF(DAY(c1) IS NULL ,'20210101',c1)的执行顺序是先计算DAY(c1)的结果,再根据结果做分支判断。INSERT场景下,DAY(c1)把'20210832'从字符串隐式转换为日期类型的步骤就已经触发了严格模式的报错,还没走到IF的替换逻辑,因此直接抛出1292 Incorrect datetime value错误。
快速验证:你可以执行
SET sql_mode = '';临时关闭严格模式,再执行INSERT语句就能正常插入数据,仅会保留转换失败的警告。
内容的提问来源于stack exchange,提问作者Hedwig
相关产品推荐
相关产品推荐

