在5.6中强化了该值设置,5.7中更注重了安全规范性,这个值默认为严格模式
一、sql_mode用来解决下面几类问题通过设置sql mode,可以完成不同严格程度的数据校验,有效保障数据准备性。
通过设置sql mode 为宽松模式,来保证大多数sql符合标准的sql语法,这样应用在不同数据库之间进行迁移时,则不需要对业务sql进行较大的修改,可以很方便的迁移到目标数据库中。
二、mysql5.7中sql_mode参数默认值的说明(如下为mysql 5.7.27版本)only_full_group_by
对于使用 group by 进行查询的sql,不允许 select 部分出现 group by 中未出现的字段,也就是 select 查询的字段必须是 group by 中出现的或者使用聚合函数的或者是具有唯一属性的。
create table test(name varchar(10),value int);insert into test values ('a',1),('a',20),('b',23),('c',15),('c',30);#默认情况是可能会写出无意义或错误的聚合语句:set sql_mode='';select * from test group by name;select value,sum(value) from test group by name;# 使用该模式后,写法必须标准set sql_mode='only_full_group_by';select name,sum(value) from test group by name;-- 错误写法则报错select value,sum(value) from test group by name;# 报错终止error 1055 (42000): expression #1 of select list is not in group by clause and contains nonaggregated column 'test.test.value' which is not functionally dependent on columns in group by clause; this is incompatible with sql_mode=only_full_group_by
strict_trans_tables
这个选项只对事务型存储引擎起作用,对非事务型存储引擎无效,其作用是启用严格 sql 模式。在strict sql模式下,在insert或者update语句中,插入或者更新了某个不符合规定的字段值,则会直接报错中断操作
create table test(value int(1));set sql_mode=''; #默认只要第一个值 insert into test(value) values('a'),(1); #不报错insert into test(value) values(2),('a'); #不报错select * from test;+------------+| value |+------------+| 0 || 1 || 2 || 0 |+------------+#后面删除表不再说明!drop table test; create table test(value int(1)); set sql_mode='strict_trans_tables'; #每个值都判断 insert into test(value) values('a'),(1);#报错,第一行'a'错误。error 1366 (hy000): incorrect integer value: 'a' for column 'value' at row 1
no_zero_in_date
mysql中插入的时间字段值,不允许日期和月份为零
create table test(value date);set sql_mode='';insert into test(value) values('2020-00-00'); #结果为 '2020-00-00' set sql_mode='no_zero_in_date';insert into test(value) values('2021-00-00'); #不符合,转为 '0000-00-00'
no_zero_date
mysql中插入的时间字段值,不允许插入 ‘0000-00-00’ 日期
create table test(value date); set sql_mode='';insert into test(value) values('0000-00-00'); #无警告 warning set sql_mode='strict_trans_tables';insert into test(value) values('0000-00-00'); #无警告 warning set sql_mode='no_zero_date';insert into test(value) values('0000-00-00'); #有警告 warning set sql_mode='no_zero_date,strict_trans_tables'insert into test(value) values('0000-00-00');# 报错终止error 1292 (22007): incorrect date value: '0000-00-00' for column 'value' at row 1
error_for_division_by_zero
insert或者update语句中,如果数据被0除,则出现警告(非strict sql模式下)或者错误(strict sql模式下)。
当该选项关闭时,数字被0除,得到null且不会产生警告
当该选项开启且处于非strict sql模式下,数字被0除,得到null但是会产生警告
当该选项开启且处于strict sql模式下,数字被0除,产生错误且中断操作
create table test(value int); set sql_mode=''; select 10/0; #无警告 warninginsert into test(value) values(10/0); #无警告 warning set sql_mode='strict_trans_tables'; select 10/0; #无警告 warninginsert into test(value) values(10/0); #无警告 warning set sql_mode='error_for_division_by_zero'; select 10/0; #有警告 warninginsert into test(value) values(10/0); #有警告 warning set sql_mode='error_for_division_by_zero,strict_trans_tables';select 10/0; #有警告 warninginsert into test(value) values(10/0); #报错:error 1365 (22012): division by 0
no_auto_create_user
禁止grant创建密码为空的用户
set sql_mode='';grant all on test.* to test01@'localhost'; #不报错(无需要设置密码)set sql_mode='no_auto_create_user';# 报错error 1133 (42000): can't find any matching row in the user table#正确 写法,需要设置密码grant all on test.* to test01@'localhost' identified by 'test01...';
no_engine_substitution
在使用create table或者alter table语法执行存储引擎的时候,如果设定的存储引擎被禁用或者未编译,会产生错误。
# 查看当前支持的存储引擎show engines;set sql_mode='';create table test(id int) engine="test";query ok, 0 rows affected, 2 warnings (0.03 sec)select table_name,engine from information_schema.tables where table_schema='test' and table_name='test'; # 转为默认存储引擎+------------+--------+| table_name | engine |+------------+--------+| test | innodb |+------------+--------+set sql_mode='no_engine_substitution';create table test(id int) engine=test;# 报错error 1286 (42000): unknown storage engine 'test'
三、sql_mode 设置和修改方式一: 这是一个可修改全局变量
> show variables like '%sql_mode%';> set @@sql_mode="no_engine_substitution"> set session sql_mode='strict_trans_tables';
方式二: 通过修改配置文件(需要重启生效)
# vim /etc/my.cnf[mysqld]......sql_mode="no_engine_substitution"......
以上就是mysql 5.7之sql_mode怎么设置的详细内容。