MySQL默认sql_mode浅析

目录
  • SQL mode
    • show sql mode
    • set sql mode
  • 默认的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
    • MySQL存储引擎

SQL mode

今天我们来分享一下MySQL的SQL mode , 这也是我们比较容易忽略的一点,我们在一开始安装数据库的时候其实就要先考虑要保留哪些SQL mode,去除哪些,合理的配置能够减少很多不必要的麻烦。

MySQL 5.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, and NO_ENGINE_SUBSTITUTION

这是MySQL官网的原文描述:“These modes were added to the default SQL mode in MySQL 5.7: The ONLY_FULL_GROUP_BY and STRICT_TRANS_TABLES modes were added in MySQL 5.7.5. The NO_AUTO_CREATE_USER mode was added in MySQL 5.7.7. The ERROR_FOR_DIVISION_BY_ZERO, NO_ZERO_DATE, and NO_ZERO_IN_DATE modes were added in MySQL 5.7.8. For additional discussion regarding these changes to the default SQL mode value, see SQL Mode Changes in MySQL 5.7.”

show sql mode

SELECT @@GLOBAL.sql_mode;

SELECT @@SESSION.sql_mode;

set sql mode

设置为GLOBAL,那么所有的客户端都会受到影响,不过要拥有SUPER权限才能进行设置,也就是root用户,设置SESSION,那么受影响的只是当前的连接会话。

SET GLOBAL sql_mode ='ONLY_FULL_GROUP_BY'

SET SESSION sql_mode ='ONLY_FULL_GROUP_BY'

下面我们就针对默认设置的这几种SQL mode进行详细的讲解,其他的哪些大家可以去官网参考。

docs.oracle.com/cd/E17952_0…

默认的SQL mode

ONLY_FULL_GROUP_BY

设置了这个值,如果使用GROUP BY,在SELECT后面出现的字段,在GROUP BY后面必须出现,不然报错如下

Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'blue.shop.price' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

如下使用的是MySQL默认的sql_mode

ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

那么下面的语句就会报错,因为GROUP BY后面只有一个字段,而SELECT * 是查出所有字段,所以就报错。

SELECT * FROM shop GROUP BY article

这样写就不会报错

SELECT * FROM shop GROUP BY article , dealer , price

不过我们不可能使用一个GROUP BY,后面还要跟着所有字段,显然不合理,那么就应该将其关闭,只需要将其去掉就行

STRICT_TRANS_TABLES

严格模式控制MySQL如何处理数据更改语句中的无效或缺失值,如INSERT或UPDATE。一个值可能因多种原因无效。例如,它可能具有列的错误数据类型,或者它可能超出了范围。如果要插入的新行不包含定义中没有显式DEFAULT子句的非null列的值,则该值缺失。

比如我们的某个字段设置不能为NULL,而我们插入的数据这个字段为NULL,那么就不能通过,就会报错如下:

1364 - Field 'dealer' doesn't have a default value

那么这个问题要怎么解决呢?我相信这个问题大家经常遇到,一般是我们在插入数据的时候实体的属性没有赋值,所以导致这个问题,所以我们会去检查代码,然后给属性赋值,另外一种做法就是去除STRICT_TRANS_TABLES,这样就不会进行校验,不过是极其不推荐这样做的,因为要我们要保证数据的完整性,所以必须在代码层面做好工作。

NO_ZERO_IN_DATE

NO_ZERO_IN_DATE模式会影响服务器是否允许年部分不为零但月或日部分为0的日期。(该模式影响日期,如“2010-00-01”或“2010-01-00”,但不影响“0000-00-00”。要控制服务器是否允许'0000-00-00',请使用NO_ZERO_DATE模式。)NO_ZERO_IN_DATE的效果还取决于是否启用严格SQL模式,如果没有启用严格SQL模式STRICT_TRANS_TABLES,那么启用了NO_ZERO_IN_DATE也没用。

如下SQL的日期月和日为0,启用了严格模式STRICT_TRANS_TABLES和NO_ZERO_IN_DATE,那么就会报错。

INSERT INTO `blue`.`shop` (`article`, `dealer` ,`price`,`date`) VALUES ('商品5', '5', 5.00, '2022-00-00');

1292 - Incorrect datetime value: '2022-00-00' for column 'date' at row 1

去除严格模式STRICT_TRANS_TABLESNO_ZERO_IN_DATE就不会报错。

NO_ZERO_DATE

上面的NO_ZERO_IN_DATE可以插入'0000-00-00',如果使用了严格模式STRICT_TRANS_TABLES和NO_ZERO_DATE,那么就不可以插入'0000-00-00'。

ERROR_FOR_DIVISION_BY_ZERO

对于INSERT或者UPDATE中,如果被除数为0,那么就会产生错误,数据无法插入,MOD(N,M)也是一样

INSERT INTO `blue`.`shop` (`article`,dealer ,`price`,`date`) VALUES ('商品5', '5', MOD(10,0), '0000-00-00');

对于SELECT,如果被除数为0,那么就会返回NULL,MOD(N,M)也一样。

SELECT price / 0  FROM shop

报错信息: 1365 - Division by 0

NO_AUTO_CREATE_USER

不能使用grant命令创建密码为空的用户。

NO_ENGINE_SUBSTITUTION

如果指定了NO_ENGINE_SUBSTITUTION,我们在创建表或者修改表的时候,如果去指定了不存在或者不支持的存储引擎,那么就会报错,无法创建和修改,如果没有配置NO_ENGINE_SUBSTITUTION,那么就会将我们指定的存储引擎(不支持或者不存在)的存储引擎替换为默认的存储引擎,MySQL5.7后的默认存储引擎为InnoDB,所以就会自动设置为InnoDB。

如下我们创建表,将存储引擎设置为一个不存在的InnoDBTest,因为我们去除了NO_ENGINE_SUBSTITUTION,所以不会报错,并且会替换成默认的InnoDB

创建sql

CREATE TABLE store ( `name` VARCHAR ( 255 ) DEFAULT NULL ) ENGINE = InnoDBTest

查看创建过程

SHOW CREATE TABLE store

结果

CREATE TABLE `store` (
  `name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

MySQL存储引擎

SHOW ENGINES;

关于MySQL的SQL mode,就说到这里,我只列举了MySQL5.7默认的几种并对其进行讲解,有兴趣的话可以去了解其他的选项

以上就是MySQL默认sql_mode浅析的详细内容,更多关于MySQL默认sql_mode的资料请关注我们其它相关文章!

(0)

相关推荐

  • MySQL出现this is incompatible with sql_mode=only_full_group_by错误的解决办法

    目录 这个就是错误截图 出现原因: MySQL的版本问题 解决办法:两种 第一种:修改MySQL的配置文件 第二种方法:修改自己的sql 总结 这个就是错误截图 出现原因: MySQL的版本问题 MySQL 5.7.5以上版本,实现了对功能依赖的检测.如果启用了only_full_group_by SQL模式(默认启用),那么MySQL就会拒绝执行 select list.HAVING condition或ORDER BY list引用既不在GROUP BY子句中被命名,也不在功能上依赖于GRO

  • mysql修改sql_mode报错的解决

    目录 一 ERR 1067引发的血案 二 问题的源头sql_mode 三 设置sql_mode 一 ERR 1067引发的血案 今天在Navicat中运行sql语句创建数据表出现了错误Err 1067.而这条语句在有些同事的mysql上是正确的,但是在有些人那里就报错.你说气不气人. 原因竟然是timestamp的默认值不正确. 查阅资料得知,mysql5.7版本中有了一个STRICT mode(严格模式),而在此模式下默认是不允许设置日期的值为全0值的,所以想要 解决这个问题,就需要修改sql

  • MySQL 5.7之关于SQL_MODE的设置

    目录 一.sql_mode用来解决下面几类问题 二.MySQL5.7中sql_mode参数默认值的说明(如下为MySQL 5.7.27版本) 三.sql_mode 设置和修改 总结 sql_mode是个容易被忽视的变量,在5.5默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入. 在5.6中强化了该值设置,5.7中更注重了安全规范性,这个值默认为严格模式 一.sql_mode用来解决下面几类问题 通过设置sql mode,可以完成不同严格程度的数据校验,有效保障数据准

  • MySQL sql_mode修改不生效的原因及解决

    前言 近期多次聊到sql_mode的话题,也是多次遇到相关问题,今天就趁热打铁,再给大家带来一个sql_mode的案例分享. 场景模拟 基于业务敏感性的考虑,下面涉及的表.存储过程等均非真实数据,但并不影响排查过程. (1)客户侧开发童鞋创建了一个存储过程,该存储过程没有严格遵守group by标准语法 session 1: mysql> delimiter // mysql> create procedure test_for_group_by() -> begin -> sel

  • MySQL sql_mode的使用详解

    前言 相信看过上一篇文章<MySQL案例:一个数据丢失惨案>的童鞋,都应该意识到,sql_mode是一个非常关键的配置,接下来就带来该配置项的详细解析. sql_mode详解 sql_mode,会直接影响SQL语法支持和数据校验,它包含非常多的选项,其中5.7版本的默认值是 "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,:ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_C

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

    在正常项目开发过程中,如果MySQL版本从5.6升级到5.7版本.作为DBA在考虑数据库版本升级带来的影响时,一般会有几个注意点: sql_mode optimizer_switch 本文主要内容是MySQL升级到5.7版本之后,由于默认的 sql_mode 值带来的坑以及对应的解决方案. 案例一:ONLY_FULL_GROUP_BY 问题描述 MySQL版本从5.6升级至5.7之后,部分SQL执行报错,报错信息如下: ERROR 1055 (42000): Expression #3 of X

  • MySQL默认sql_mode浅析

    目录 SQL mode show sql mode set sql mode 默认的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 MySQL存储引擎 SQL mode 今天我们来分享一下MySQL的SQL mode , 这也是我们比较容易忽略的一点,我

  • MySQL关于sql_mode解析与设置讲解

    昨晚在往MySQL数据库中插入一组数据时,出错了!数据库无情了给我报了个错误:ERROR 1365(22012):Division by 0:意思是说:你不可以往数据库中插入一个 除数为0的运算的结果.于是乎去谷歌了一番,总算是明白了其中的原因:是因为MySQL的sql_mode 模式限制着一些所谓的'不合法'的操作. 解析 这个sql_mode,简而言之就是:它定义了你MySQL应该支持的sql语法,对数据的校验等等.. 如何查看当前数据库使用的sql_mode: mysql> select

  • 关于MySQL的sql_mode合理设置详解

    MySQL的sql_mode合理设置 sql_mode是个很容易被忽视的变量,默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入.在生产环境必须将这个值设置为严格模式,所以开发.测试环境的数据库也必须要设置,这样在开发测试阶段就可以发现问题. 1.sql model 常用来解决下面几类问题: (1) 通过设置sql mode, 可以完成不同严格程度的数据校验,有效地保障数据准备性. (2) 通过设置sql model 为宽松模式,来保证大多数sql符合标准的sql语法

  • 详解MySQL的sql_mode查询与设置

    1,执行SQL查看 select @@session.sql_mode; 全局级别: 查看 select @@global.sql_mode; 2,修改 set @@session.sql_mode='xx_mode' set session sql_mode='xx_mode' 全局级别:修改 set global sql_mode='xx_mode'; set @@global.sql_mode='xx_mode'; session均可省略,默认session,仅对当前会话有效 全局修改的话

  • MySQL默认字符集设置详情

    目录 查看各版本默认字符集 修改MySQL5中的默认字符集 已有库&表字符集的变更 各级别的字符集 字符集与比较规则 utf8 与 utf8mb4 比较规则 请求到响应过程中字符集的变化 SQL大小写规范 Windows和Linux平台区别 SQL编写建议 sql_mode的合理设置 宽松模式 严格模式 查看各版本默认字符集 在MySQL 8.0版本之前,默认字符集为latin1 ,utf8字符集指向的是utf8mb3 .网站开发人员在数据库设计的时候往往会将编码修改为utf8字符集.如果遗忘修

  • Mysql默认设置的危险性分析第1/2页

    默认安装的mysql服务不安全因素涉及的内容有: 一.mysql默认的授权表 二.缺乏日志能力 三.my.ini文件泄露口令 四.服务默认被绑定全部的网络接口上 五.默认安装路径下的mysql目录权限 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 一.mysql默认的授权表 由于mysql对身份验证是基于mysql这个数据库的,也叫授权表.所有的权限设置都在这里了. 我们只讨论最为重要的一个表 user表.它控制的是接受或拒绝连接. 先看一下 se

  • xampp修改mysql默认密码的方法

    在这里介绍xampp修改mysql默认密码的大概过程是先利用xampp的phpmyadmin进入修改mysql密码,修改之后我们再修改xampp中phpmyadmin的密码,这样就完整的修改mysql默认密码了. 大概过程 在mysql里设密码打开IE输入网址localhostphpadmin之后,点用户看到有root用户,往下拉,找到修改密码的地方,输入密码,进行执行操作,最后再去到在你的xampp安装目录下找到phpadmin文件夹,打开找到config.inc.php文件之后,打开找关于m

  • 修改mysql默认字符集的两种方法详细解析

    (1) 最简单的修改方法,就是修改mysql的my.ini文件中的字符集键值,如 default-character-set = utf8    character_set_server = utf8 修改完后,重启mysql的服务,service mysql restart使用 mysql> SHOW VARIABLES LIKE 'character%';查看,发现数据库编码均已改成utf8 复制代码 代码如下: +--------------------------+-----------

  • mysql默认编码为UTF-8 通过修改my.ini实现方法

    mysql汉字乱码的原因 mysql默认的编码是Latin1是I-8859-1的别名,但Latin1是不支持汉字的,所以要将其改为UTF-8或GBK 1.关闭mysql服务器,这个很重要. 2.通过my.ini设置mysql数据库的编码 在mysql数据库的安装根目录下找到my.ini,例:C:\Program Files\MySQL\MySQL Server 5.5 将其复制到桌面,双击打开, 搜索"default-character-set"将其改为utf8, 搜索"ch

随机推荐