MySQL学习——sql_mode(2)

0、参考资料

http://xstarcd.github.io/wiki/MySQL/MySQL-sql-mode.html
http://blog.csdn.net/wulantian/article/details/8905573
https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html
http://blog.csdn.net/wyzxg/article/details/8787878
https://blog.linuxeye.cn/379.html

1、技术场景

项目最近架构调整,老架构MySQL版本是5.6,新架构升级了一下MySQL版本,升级到了5.7。升级之后发现很多地方报错,都是MySQL相关的错误。
下面一个错误一个错误的分析。

错误一:

MySQL [pdmp]> select Fname,Fsource_name_code from t_data_source where Fenable = 'Y'  and site = 'friso' group by Fsource_name_code;
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'pdmp.t_data_source.Fname' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

从报错分析,是因为select的字段(非聚合函数),没有全部在group by中。那之前在老架构的MySQL的版本中能正常运行,新架构怎么就不行了?猜想应该是版本升级导致的。
去查看了一下老版本的sql_mode,结果如下:

SELECT @@GLOBAL.sql_mode;
+------------------------+
| @@GLOBAL.sql_mode      |
+------------------------+
| NO_ENGINE_SUBSTITUTION |
+------------------------+

没有严格模式等相关限制。
再看看新版本的sql_mode,结果如下:

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_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+

问题就出在ONLY_FULL_GROUP_BY上,去查了一下,如果添加上这个模式,
对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么这个SQL是不合法的,因为列不在GROUP BY从句中。

错误二:

INSERT  INTO `t_data_source`(`Fname`, `Fbrand`, `Fmarketing_type`, `Fdata_type`, `Fcreate_time`, `Factive`, `Fsource_name_code`, `site`) VALUES ('巴啦啦', 'ADF', '2', '1', '2018-03-12 09:46:07', '', '1', 'friso');
dispatch exception:SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'Factive' at row 1

从SQL报错上分析,可以很容易知道,是因为数据库字段类型和插入数据类型不匹配导致的。初步猜想和错误一的原因一致。后来发现是因为模式STRICT_TRANS_TABLES导致的,在这种模式下:如果一个值不能插入到一个事务表中,则中断当前的操作,对非事务表不做限制。而我们刚好是开启事务的。

2、sql_mode介绍

介绍都是官网搬过来的。

ONLY_FULL_GROUP_BY:

对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么这个SQL是不合法的,因为列不在GROUP BY从句中。

STRICT_TRANS_TABLES:

在该模式下,如果一个值不能插入到一个事务表中,则中断当前的操作,对非事务表不做限制。

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:

如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常。

PIPES_AS_CONCAT:

将"||"视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样的,也和字符串的拼接函数Concat相类似。

ANSI_QUOTES:

启用ANSI_QUOTES后,不能用双引号来引用字符串,因为它被解释为识别符

3、修改sql_mode配置

查看sql_mode

select @@sql_mode;
show variables like 'sql_mode%'G;

sql_mode修改

set @@sql_mode=TRADITIONAL;

另外,可以直接修改my.ini文件,找到sql_mode,然后设置新的模式即可!

例如:

vi /etc/my.cnf

在[mysqld]下面添加如下列:

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
原文地址:https://www.cnblogs.com/jaspersong/p/8551149.html