如何配置MySQL使smallint列插入非法值时报错而非自动修正
MySQL 5.7 拒绝非法值自动转换的配置方法
出现smallint类型列插入时越界值被截断、空输入被转成0且不报错的问题,核心原因是MySQL服务未开启严格SQL模式,按以下步骤配置即可让数据库遇到非法输入时直接抛出错误、拒绝写入:
配置方式
临时生效(重启MySQL后失效)
直接在MySQL命令行执行对应命令,可按需选择生效范围:
- 全局生效:对配置执行完成后所有新建立的客户端连接生效
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'; - 当前会话生效:仅对当前正在使用的数据库连接生效
SET SESSION sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
说明:如果使用的是MyISAM这类非事务存储引擎,把配置里的
STRICT_TRANS_TABLES替换为STRICT_ALL_TABLES,即可对所有存储引擎的表开启严格值校验。其中STRICT_TRANS_TABLES仅对InnoDB等事务型表生效,遇到非法值时会直接中断语句执行、抛出错误,不会做静默的截断或值转换。
永久生效(重启服务不失效)
需要修改MySQL配置文件,步骤如下:
- 找到对应系统的MySQL配置文件:Linux环境通常路径为
/etc/my.cnf或/etc/mysql/my.cnf,Windows环境通常为MySQL安装目录下的my.ini - 在配置文件的
[mysqld]段落下添加/修改sql_mode配置项:[mysqld] sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION - 保存配置文件后重启MySQL服务:Linux环境可执行
systemctl restart mysqld完成重启,Windows环境可在系统服务管理器中找到MySQL服务执行重启操作。
配置校验
配置完成后重新建立MySQL连接,执行以下命令检查配置是否生效:
SELECT @@sql_mode;
返回结果中包含STRICT_TRANS_TABLES(或STRICT_ALL_TABLES)即代表严格模式已正常开启。
开启严格模式后,提到的两类异常场景都会直接触发错误:
- 向smallint列插入超出
-32768~32767范围的数值时,会直接抛出Out of range value for column类错误,不会被自动截断为边界值 - 向定义为
NOT NULL且无默认值的smallint列插入空输入时,会直接抛出字段不允许为空的错误,不会被静默转换为0
注意:如果字段本身允许为NULL、或显式设置了默认值0,插入空值时按字段定义规则处理属于正常逻辑,不属于自动转换的异常范畴。
内容的提问来源于stack exchange,提问作者Rob Salusbury
相关产品推荐
相关产品推荐

