前言
事发
最近有个版本要求修改评论长度限制,由64改为500,在调试过程中,评论始终只能显示出来200字,经过查库,发现字段长度被定为200,插入时被截断。超出长度不是因该报错吗?嗯,应该是sql_mode的问题。
验证
1 | Sql复制代码## 创建表 username 长度为8 |
SQL_MODE
MySQL服务器可以在不同的模式设置(sql_mode)下运行,并可以对不同的客户端进行不同的设置,通过sql_mode变量设置。
影响点:
- 语法
- 数据校验
设置SQL_MODE
默认的sql_mode值为NO_ENGINE_SUBSTITUTION,可在启动时及运行时设置该变量。
启动时设置:
- 启动时命令行添加 —sql-mode=”A,B,C……”(多值使用“,”隔开)
- 在my.cnf配置文件中添加sql-mode=”A,B,C……”(多值使用“,”隔开)
运行时设置:
1 | Sql复制代码SET GLOBAL sql_mode = 'A,B,C……'; ## 全局 重连生效 |
查看:
1 | sql复制代码- SELECT @@GLOBAL.sql_mode |
注意:
- 在表使用分区后,最好不要改变sql_mode,因为不同的sql_mode会影响一些计算结果,对分区策略产生影响
- 主从服务器,使用相同的sql_mode,以实现数据同步
SQL_MODE可选值
其它几个影响语法及数据校验的值
- ALLOW_INCALID_DATES
不校验时间的有效性,只会校验月在1-12之间,日在1-31之间,只针对DATE和DATETIME类型有效,对TIMESTAMP无效。
1 | Sql复制代码insert into temp values('2019-02-31 01:01:01'); |
1 | Sql复制代码set SESSION sql_mode = 'ALLOW_INVALID_DATES'; |
- ANSI_QUOTES
双引号(“)被用作标识符引用字符,和“`”相同。
1 | Sql复制代码truncate table "temp"; |
1 | Sql复制代码set SESSION sql_mode = 'ANSI_QUOTES'; |
- ERROR_FOR_DEVISION_BY_ZERO
控制/0及mod(n,0)的验证,该模式开启后可/0及mod(n,0)操作会生成警告,如果此时开启了严格SQL模式(STRICT_TRANS_TABLES 或 STRICT_ALL_TABLES),会阻止语句执行,报错。不影响select语句。
- HIGH_NOT_PRECEDENCE
提高逻辑运算NOT优先级
1 | Sql复制代码select not 1; |
- ONLY_FULL_GROUP_BY
影响group by语法
1 | Sql复制代码select count(0) ct,username from test group by pwd; |
更多
以上列举了几个对编码影响较大的选项,更多选项见官网说明。
总结
以后关于SQL的写法,和某人抬杠时,除了要确定MySQL版本之外,还要问一句,您是啥sql_mode…….O(∩_∩)O哈!。
本文转载自: 掘金