MySQL5.7中的sql_mode默认值带来的坑及解决方法

MySQL5.7中的sql_mode默认值带来的坑及解决方法

在MySQL5.7版本中,sql_mode的默认值发生了变化,从之前的空值改成了ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION这些选项的组合。这种默认值存在一些问题,比较常见的有以下两种情况:

  1. 对旧版本的代码迁移会有影响,出现Illegal mix of collations(字符集不一致)等错误;
  2. 自动生成时间戳的值不再支持0000-00-00这种情况,而且对于无效或不合法的日期,MySQL将抛出错误而不再返回NULL

为了避免这些问题,在使用MySQL5.7之前,需要对sql_mode进行设置,或者在升级后适时调整sql_mode的值。

设置方法:

可以通过以下两种方法设置sql_mode的值:

  1. 修改MySQL配置文件:打开MySQL配置文件my.cnf,并在[mysqld]部分中加入sql_mode设置,例如:

[mysqld]
sql_mode=ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

然后重启MySQL服务使其生效。

  1. 直接在MySQL命令行下执行SET sql_mode命令,例如:

SET sql_mode='ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

这种方法可以动态设置sql_mode的值,并不需要重启MySQL服务。

示例说明:

  1. 案例1:旧版代码迁移失败

假设存在一个表test,其中有两个字段idname,定义如下:

CREATE TABLE test(
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(20) COLLATE utf8mb4_general_ci DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

然后执行以下语句:

SELECT name FROM test GROUP BY name;

在MySQL5.6版本中,上述语句没有问题,可以正常执行。但在MySQL5.7版本中,会遇到以下错误:

ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'test.name' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

出错原因是在默认sql_mode中包含了ONLY_FULL_GROUP_BY选项,导致在GROUP BY语句中必须将所有字段都列出,否则会抛出错误。在这种情况下,可以通过修改sql_mode来解决问题。

  1. 案例2:生成时间戳失败

在MySQL5.7中,如果要插入一个0000-00-00日期,或者一个非法日期,例如2017-02-31(2月只有28/29天),MySQL会抛出以下错误:

ERROR 1292 (22007): Incorrect date value: '0000-00-00' for column 'c' at row 1

这是由于默认sql_mode中包含了NO_ZERO_IN_DATENO_ZERO_DATE选项,导致MySQL不再支持0000-00-00这种日期格式,而且对于无效或不合法的日期,仅返回错误而不是NULL

解决方法可以将这两个选项从sql_mode中删掉,例如:

SET sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

这样,在插入0000-00-00日期或非法日期时,MySQL会返回NULL而不再抛出错误。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:MySQL5.7中的sql_mode默认值带来的坑及解决方法 - Python技术站

(0)
上一篇 2023年5月18日
下一篇 2023年5月18日

相关文章

  • mysql中错误:1093-You can’t specify target table for update in FROM clause的解决方法

    首先,让我们来了解一下这个错误的含义:1093错误是出现在MySQL UPDATE语句中,它的意思是你不能在更新语句的FROM子句中指定目标表。这是MySQL的限制,因为它会导致循环引用的可能性,可能会导致死锁。 解决方法有两种,下面一一介绍: 方法一:使用子查询 使用子查询可以将需要更新的表放在子查询中,避免了直接更新的目标表无法使用它自身的值的限制。 示…

    MySQL 2023年5月18日
    00
  • Centos7中MySQL数据库使用mysqldump进行每日自动备份的编写

    下面是在CentOS7中使用mysqldump进行每日自动备份的完整攻略: 确保MySQL和mysqldump安装 首先,我们需要确保MySQL和mysqldump已经安装。如果没有安装,使用以下命令安装: sudo yum install mysql-server mysql sudo yum install mysql-devel sudo yum in…

    MySQL 2023年5月19日
    00
  • 在php 扩展中 调用mysql

    call_user_function_ex是php提供的一个c api,具体的参数也没有一个官方的文档。我给你一个例子并稍微说明一下吧。 C/C++ code zval *fname; zval **args[1]; zval *retval; zval *arg1; args[0]=&arg1; int arg_count=1; call_user…

    MySQL 2023年4月13日
    00
  • mysql开启慢查询(EXPLAIN SQL语句使用介绍)

    下面是mysql开启慢查询以及使用EXPLAIN SQL语句的完整攻略。 什么是慢查询 慢查询是指在mysql数据库中,执行时间超过一定时间阈值的查询操作,一般认为执行时间超过一秒的查询为慢查询。慢查询的原因可能是表设计不合理,查询语句不够优化,索引缺失等。 因此,在进行web开发时,我们需要对慢查询进行优化,提高网站的性能和用户体验。 开启慢查询功能 在m…

    MySQL 2023年5月19日
    00
  • 解决mysql ERROR 1045 (28000)– Access denied for user问题

    针对 mysql ERROR 1045 (28000)– Access denied for user 的问题,通常有以下三种解决办法: 1. 修改或重置 root 密码 步骤1:停止 MySQL 服务 在命令行输入以下命令停止 MySQL 服务: sudo systemctl stop mysql 步骤2:使用 -skip-grant-tables 参数…

    MySQL 2023年5月18日
    00
  • MySQL基本命令脚本

    MySQL基本命令脚本:  一、基本命令   1、启动服务:     说明:以管理员身份运行cmd     格式:net start 服务名称     示例:net start mysql57;     2、停止服务:     说明:以管理员身份运行cmd     格式:net stop 服务名称     示例:net stop mysql57;     3…

    MySQL 2023年4月13日
    00
  • MySQL 5.5.49 大内存优化配置文件优化详解

    MySQL 5.5.49 大内存优化配置文件优化详解 背景 随着数据量的增长,MySQL 数据库所使用的内存也变得越来越多,如果不对MySQL 进行优化,可能会使数据库性能严重下降。本文将介绍如何针对MySQL 5.5.49版进行大内存优化和配置文件优化,以提高MySQL的性能。 大内存优化 MySQL的大内存优化主要包括以下几个方面: 1. 与系统内存的交…

    MySQL 2023年5月19日
    00
  • 解析mysql中:单表distinct、多表group by查询去除重复记录

    很高兴为你讲解“解析mysql中:单表distinct、多表group by查询去除重复记录”的完整攻略。 什么是MySQL中的distinct? 在MySQL中,DISTINCT是一种用于从查询结果中删除重复项的选择器。它保留一个副本,并删除所有重复项。如果要在结果集中查找唯一的值,那么可以使用DISTINCT选择器。 在单表查询中,DISTINCT将会对…

    MySQL 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部