sql modemysql 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 modeselect @@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 modeonly_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_tablesmysql的严格模式可以控制如何处理insert或update语句中的无效或缺失的值。一个值可能因多种原因无效。例如,它可能具有列的错误数据类型,或者它可能超出了范围。缺少非空列的值没有在定义中明确指定默认值,则插入的新行会出现该问题。
比如我们的某个字段设置不能为null,而我们插入的数据这个字段为null,那么就不能通过,就会报错如下:
1364 - field 'dealer' doesn't have a default value
那么这个问题要怎么解决呢?我相信这个问题大家经常遇到,一般是我们在插入数据的时候实体的属性没有赋值,所以导致这个问题,所以我们会去检查代码,然后给属性赋值,另外一种做法就是去除strict_trans_tables,这样就不会进行校验,不过是极其不推荐这样做的,因为要我们要保证数据的完整性,所以必须在代码层面做好工作。
no_zero_in_dateno_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_tables和no_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怎么设置的详细内容。