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.32MariaDB 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_DATENO_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 查询失败的主要内容,如果未能解决你的问题,请参考以下文章

mysql 8.0.16 源码编译[Mac os x平台]

Linux 6.7 安装 MySQL 8.0.16

MySql-8.0.16版本部分安装问题修正

MySQL-mysql 8.0.16安装教程

Django 连接 Mysql (8.0.16) 失败

MySql-8.0.16-winx64 安装