mysql mode模式_MySQL 的 mysql_mode 模式设置

数据表中某字段没有设置了默认值,所以在写 insert 语句时没有添加该字段,就出现了问题,告诉我该字段没有插入数据,我不是设置了默认值了吗?按理说插入的时候不添加该字段也可以啊,但是报错了,后来排查因为 sql_mode 设置的问题。

什么是 sql_mode,官方手册中有一节介绍:https://dev.mysql.com/doc/refman/5.6/en/sql-mode.html 的意思。简单理解下就是:mysql 服务器可以在不同的 sql 模式下运行,并且可以针对不同的客户端以不同的方式应用这些模式,具体取决于 sql_mode 系统变量的值。我们可以设置全局 sql 模式以匹配站点服务器操作要求,并且每个应用程序可以将其会话 sql 模式设置为其自己的要求。

查看 sql_mode 设置mysql> show variables like 'sql_mode';

+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+

| Variable_name | Value                                                                                                                                     |

+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+

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

+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+

sql_mode 各参数说明:ONLY_FULL_GROUP_BY

对于 group by 操作,如果在 select 中的列,没有在 group by 中出现,那么将认为这个 sql 是不合法的,因为列不在 group by 从句中,会报一个 ERROR 1055 (42000): ...

STRICT_TRANS_TABLES

存储引擎启用严格 sql 模式

NO_ZERO_IN_DATE

在严格模式,不接受月或日部分为 0 的日期。如果使用 IGNORE 选项,我们为类似的日期插入'0000-00-00'。在非严格模式,可以接受该日期,但会生成警告

NO_ZERO_DATE

在严格模式,不要将 '0000-00-00'做为合法日期。你仍然可以用 IGNORE 选项插入零日期。在非严格模式,可以接受该日期,但会生成警告

ERROR_FOR_DIVISION_BY_ZERO

在严格模式,在 insert 或 update 过程中,如果被零除(或MOD(X,0)),则产生错误(否则为警告)。如果未给出该模式,被零除时 mysql 返回 null。如果用到 INSERT IGNORE 或 UPDATE IGNORE 中,mysql 生成被零除警告,但操作结果为NULL

NO_AUTO_CREATE_USER

防止 GRANT 自动创建新用户,除非还指定了密码。

NO_ENGINE_SUBSTITUTION

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

修复 INSERT 语句报错的问题

经过翻阅官方手册得知 STRICT_TRANS_TABLES 启用严格 sql 模式,如果 insert 语句不包含该列的值,则会抛出一个错误,为了便于 sql 的灵活性,我们把这个 STRICT_TRANS_TABLES 删除。mysql> set sql_mode=(select replace(@@sql_mode,'STRICT_TRANS_TABLES',''));

查看 sql_mode 设置mysql> show variables like 'sql_mode';

+---------------+-----------------------------------------------------------------------------------------------------------------------+

| Variable_name | Value                                                                                                                 |

+---------------+-----------------------------------------------------------------------------------------------------------------------+

| sql_mode      | ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |

+---------------+-----------------------------------------------------------------------------------------------------------------------+

我们已经去掉了 STRICT_TRANS_TABLES 这个参数,下面执行插入语句返回 Query OK, 0 rows affected, 1 warning (0.00 sec)。成功了,但是呢,等我返回浏览器执行添加操作却再次失败,纳尼?刚才测试的不是成功了吗?为什么在 mysql 命令行中可以执行成功,但是浏览器中不可以呢?原来这里设置的 sql_mode 对全局没有影响,还有一个 global.sql_mode,那我们也得把 global.sql_mode 设置下。mysql> show global variables like 'sql_mode';

+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+

| Variable_name | Value                                                                                                                                     |

+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+

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

+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+

果然!STRICT_TRANS_TABLES 它还在,也把它去掉。mysql> set @@global.sql_mode=(select replace(@@global.sql_mode,'STRICT_TRANS_TABLES',''));

查看全局 sql_mode 设置mysql> show global variables like 'sql_mode';

+---------------+-----------------------------------------------------------------------------------------------------------------------+

| Variable_name | Value                                                                                                                 |

+---------------+-----------------------------------------------------------------------------------------------------------------------+

| sql_mode      | ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |

+---------------+-----------------------------------------------------------------------------------------------------------------------+

我们已经去掉全局中的 STRICT_TRANS_TABLES 这个参数,返回浏览器中执行添加,添加成功,你以为这就完了吗?其实没有,如果你不重启 mysql 服务的话那这样就可以了。那如果重启呢?还是不行,所以我们直接改 my.cnf 配置文件吧。# my.cnf 配置文件

.

.

.

[mysqlhotcopy]

interactive-timeout

sql_mode=ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

打开 my.cnf 文件,发现我的 sql_mode 并没有设置 STRICT_TRANS_TABLES 这个参数啊,为什么不行呢?原来这个设置没有放在 [mysqld] 下面,我们把它挪下位置,直接在后面追加就好。[mysqld]

.

.

.

sql_mode=ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

保存后重启 mysql 服务,返回浏览器执行添加,成功。因为默认 mysql 没有配置 STRICT_TRANS_TABLES 参数,所以我只是挪动了下位置,大家可以根据实际情况来修改 sql_mode 的参数值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值