sql_mode介绍
sql_mode设置是否允许一些非法操作,比如允许一些非法数据的插入,数据查询等。
在生产环境必须将这个值设置为严格模式,所以开发、测试、生产环境的数据库也必须要设置,这样在开发测试阶段就可以发现问题。
select @@GLOBAL.sql_mode;全局的sql_mode
select @@SESSION.sql_mode;会话级别sql_mode
查看相关的sql_mode配置
linux下
执行sql:select @@GLOBAL.sql_mode;
| @@GLOBAL.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_SUBSTITUTI |
结论:
linux下,有ONLY_FULL_GROUP_BY,所以在linux中分组查询中,
查询字段只允许 分组字段 聚合函数,
如:select user_id,max(user_age) from user group by user_id;
windows下
执行sql:select @@GLOBAL.sql_mode;
得到如下结果:STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
#因为并没有ONLY_FULL_GROUP_BY标识,也就不是严格模式
当前分组查询可以直接:select * from group by user_id;
其他标识简介
Ø sql_mode常用值如下:
set sql_mode='ONLY_FULL_GROUP_BY';
Ø ONLY_FULL_GROUP_BY:对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么这个SQL是不合法的,因为列不在GROUP BY从句中
Ø NO_AUTO_VALUE_ON_ZERO:该值影响自增长列的插入。默认设置下,插入0或NULL代表生成下一个自增长值。如果用户希望插入的值为0,而该列又是自增长的,那么去掉该选项。
Ø STRICT_ALL_TABLES,STRICT_TRANS_TABLES
对于支持事务的表,这两种模式是一样的:如果发现某个值缺失或非法,MySQL将抛出错误,语句会停止运行并回滚。
对于不支持事务的表,这两种模式的效果:
1、如果在插入或修第一个数据行时就发现某个值非法或缺失,那该语句直接抛错,语句停止执行。这个和支持事务的数据表行为时一样的。
2、如果在插入或修改第n个(n>1)数据行时才发现错误,那就会出现下面的情况:
2.1 在STRICT_ALL_TABLES模式下,停止语句执行,存在部分更新的问题
2.2 在STRICT_TRANS_TABLES模式下,MySQL将继续执行该语句避免“部分更新问题”,对每个非法值将其转换为最接近的合法值。
Ø NO_ZERO_IN_DATE:在严格模式下,不允许日期和月份为零
Ø NO_ZERO_DATE:设置该值,mysql数据库不允许插入零日期,插入零日期会抛出错误而不是警告。
Ø ERROR_FOR_DIVISION_BY_ZERO:在INSERT或UPDATE过程中,如果数据被零除,则产生错误而非警告。如果未给出该模式,那么数据被零除时MySQL返回NULL
Ø NO_AUTO_CREATE_USER:禁止GRANT创建密码为空的用户
Ø NO_ENGINE_SUBSTITUTION:如果需要的存储引擎被禁用或不存在,那么抛出错误。不设置此值时,用默认的存储引擎替代