SQL Mode 可以解决下面这几种问题
通过设置 SQL Mode,可以完成不同严格程度的数据校验,有效保障数据的准确性。
设置 SQL Mode 为ANSI模式,来保证大多数 SQL 符合标准的 SQL 语法,这样应用在不同数据库的迁移中,不需要对 SQL 进行较大的改变
数据在不同数据库的迁移中,通过改变 SQL Mode 能够更方便的进行迁移。
下面我们就通过示例来演示一下 SQL Mode 用法
我们可以通过
select @@sql_mode;
来查看默认的 SQL Mode,如下是我的数据库所支持的 SQL Mode
涉及到很多 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。
ERROR_FOR_DIVISION_BY_ZERO:如果这个模式未启用,那么零除操作将会插入空值并且不会产生警告;如果这个模式启用,零除操作插入空值并产生警告;如果这个模式和严格模式都启用,零除从操作将会产生一个错误。
NO_AUTO_CREATE_USER:禁止使用 grant 语句自动创建用户,除非认证信息被指定。
NO_ENGINE_SUBSTITUTION:此模式指定当执行 create 语句或者 alter 语句指定的存储引擎没有启用或者没有编译时,控制默认存储引擎的自动切换。默认是启用状态的。