涉及到很多 SQL Mode,下面是这些 SQL Mode 的解释
ONLY_FULL_GROUP_BY:这个模式会对 GROUP BY 进行合法性检查,对于 GROUP BY 操作,如果在SELECT 中的列,没有在 GROUP BY 中出现,那么将认为这个 SQL 是不合法的,因为列不在 GROUP BY 从句中
同样举个例子,我们现在查询一下 cxuan005 的 id 和 info 字段。
select id,info from cxuan005;这样是可以运行的
然后我们使用 GROUP BY 字句进行分组,这里只对 info 进行分组,我们看一下会出现什么情况
select id,info from cxuan005 group by info;我们可以从错误原因中看到,这条 SQL 语句是不符合 ONLY_FULL_GROUP_BY 的这条 SQL Mode 的。因为我们只对 info 进行分组了,没有对 id 进行分组,我们把 SQL 语句改成如下形式
select id,info from cxuan005 group by id,info;这样 SQL 就能正确执行了。
当然,我们也可以删除 sql_mode = ONLY_FULL_GROUP_BY 的这条 Mode,可以使用
SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));来进行删除,删除后我们使用分组语句就可以放飞自我了。
select id,info from cxuan005 group by info;但是这种做法只是暂时的修改,我们可以修改配置文件 my.ini 中的 sql_mode= STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
STRICT_TRANS_TABLES:这就是严格模式,在这个模式下会对数据进行严格的校验,错误数据不能插入,报error 错误。如果不能将给定的值插入到事务表中,则放弃该语句。对于非事务表,如果值出现在单行语句或多行语句的第1行,则放弃该语句。
当使用 innodb 存储引擎表时,考虑使用 innodb_strict_mode 模式的 sql_mode,它能增量额外的错误检测功能。
NO_ZERO_IN_DATE:这个模式影响着日期中的月份和天数是否可以为 0(注意年份是非 0 的),这个模式也取决于严格模式是否被启用。如果这个模式未启用,那么日期中的零部分被允许并且插入没有警告。如果这个模式启用,那么日期中的零部分插入被作为 0000-00-00 并且产生一个警告。
这个模式需要注意下,如果启用的话,需要 STRICT_TRANS_TABLES 和 NO_ZERO_IN_DATE 同时启用,否则不起作用,也就是
set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE';然后我们换表了,使用 cxuan003 这张表,表结构如下
我们主要测试日期的使用,在 cxuan003 中插入一条日期为 0000-00-00 的数据
insert into cxuan003 values(111,'study','0000-00-00');发现能够执行成功,但是把年月日各自变为 0 之后再进行插入,则会插入失败。
insert into cxuan003 values(111,'study','2021-00-00'); insert into cxuan003 values(111,'study','2021-01-00');这些组合有很多,我这里就不再细致演示了,读者可以自行测试。
如果要插入 0000-00-00 这样的数据,必须设置 NO_ZERO_IN_DATE 和 NO_ZERO_DATE。