MySQL 8.0.16:Select Date LIKE 查询失败
Posted
技术标签:
【中文标题】MySQL 8.0.16:Select Date LIKE 查询失败【英文标题】:MySQL 8.0.16: Select Date LIKE query fails 【发布时间】:2021-03-15 05:29:04 【问题描述】:我有 3 台 mysql/MariaDB 服务器正在运行,用于应用程序开发和测试:
MySQL Community Server 5.7.32
MySQL Community Server 8.0.16
MariaDB Community Server 10.4.12
服务器被配置为在同一台机器上的不同端口上运行。
SELECT @@sql_mode
适用于所有服务器:
MySQL Community Server 5.7.32
: NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
MySQL Community Server 8.0.16
: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
MariaDB Community Server 10.4.12
: NO_ZERO_IN_DATE,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION
我在我维护的旧代码中偶然发现了一些 SELECT 查询,这些查询无法运行,例如搜索具有给定模式的日期。查询如下所示:
SELECT * FROM `userTable` WHERE `birthDate` LIKE '2020-%-%';
SELECT * FROM `userTable` WHERE `birthDate` LIKE '%12%';
表格如下所示:
CREATE TABLE IF NOT EXISTS `userTable` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` TEXT COLLATE utf8_unicode_ci,
`birthDate` DATE,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
当我在 MySQL Community Server 8.0.16
上运行查询时,它们会因错误 Error Code: 1525. Incorrect DATE value: '2020-%-%'.
和 Error Code: 1525. Incorrect DATE value: '%12%'.
而失败。
MySQL Community Server 5.7.32
和MariaDB Community Server 10.4.12
成功执行查询。
为什么MySQL Community Server 8.0.16
无法执行这些 SELECT 查询?
PS:第一个SELECT查询可以写成
SELECT * FROM `userTable` WHERE YEAR(`birthDate`) = 2020;
在所有 3 台服务器上运行。
编辑:这是MySQL Community Server 8.0.16
中的一个错误,已在版本8.0.22
中修复。
【问题讨论】:
无法重现:dbfiddle.uk/… 添加您的源数据并重现问题。 为什么 MySQL Community Server 8.0.16 无法执行这些 SELECT 查询? 显示所有服务器的SELECT @@sql_mode;
输出。 NO_ZERO_DATE
和 NO_ZERO_IN_DATE
可能是一个原因。
Akina 我把它加到问题里了
添加了模式不是默认的,所以除此之外没有任何配置被改变。不正确。 PS。您是否找到了值导致问题的行?他们会在小提琴上产生同样的错误吗?
是查询错误,不是数据错误
【参考方案1】:
您应该将真实的日期列与有效的日期文字进行比较,not 字符串,例如寻找2020年的记录:
SELECT *
FROM userTable
WHERE birthDate >= '2020-01-01' AND birthDate < '2021-01-01'; -- sargable :-)
或许:
SELECT *
FROM userTable
WHERE YEAR(birthDate) = 2020; -- not sargable though :-(
【讨论】:
这不能回答我的问题,也不能解释为什么查询不能在较新的 MySQL 服务器上运行 这与演员规则的变化有关,但千万别走那条路。我的意思是,无论解释如何,都不会改变这种情况。 尤其是第二个查询,应用程序应该能够搜索日期包含“12”的所有条目,给出类似 1912-05-15、2020-12-03 和 2020-05-的结果12等 如果你真的想这样做(坏主意),那么首先在日期列上使用DATE_FORMAT
,然后将其与LIKE
表达式进行比较。不要直接比较日期(最好使用我的答案)。
@fireandfuel 。 . .这是编写代码的正确方法。从性能的角度来看,将日期转换为字符串是一个坏主意。依赖隐式格式只会使您的代码容易受到错误的影响,并引发性能问题并使其难以理解。以上是关于MySQL 8.0.16:Select Date LIKE 查询失败的主要内容,如果未能解决你的问题,请参考以下文章