我有一个带有字段DECIMAL(9,2)
的表,我有两个运行mysql 5.7的服务器
如果我运行此代码
INSERT INTO `money_accounts` (`balance`) VALUES (9999999999.99);
在其中一个服务器上插入并且值被截断,另一个则引发Out of range value for column balance
错误。
我的问题是,实现这一目标的配置值是什么?或者为什么它发生在一个服务器而不是另一个服务器?
答案 0 :(得分:2)
定义
DECIMAL(9,2)
表示总精度的9位数,小数位后的位数为2位。值
9999999999.99
有12位精度数字,小数点后2位。因此,该值超出范围。理所当然,MySQL应该在两种情况下抛出超出范围的错误。在它工作的情况下,"我的猜测是发生了截断。
顺便说一句,您应该使用DECIMAL(12,2)
或更宽版本来存储问题中的值。
<强>更新强>
一个可能的解释为什么你的一个服务器正在插入而另一个服务器失败的原因是第一个服务器关闭了传统模式。在两台服务器上运行以下命令:
SELECT @@SESSION.sql_mode
如果您看到输出看起来像
STRICT_TRANS_TABLES, STRICT_ALL_TABLES, ...
然后服务器以传统模式运行,这意味着它不会被截断但会拒绝。要关闭它,请尝试运行
SET SESSION sql_mode=''
他们插入应该成功(截断)。但无论如何,你应该不依赖于生产中的截断。如果您需要更高的精度,请加宽色谱柱。
参考:Automatically trimming length of string submitted to MySQL
答案 1 :(得分:1)
如果我们阅读文档:http://dev.mysql.com/doc/refman/5.7/en/out-of-range-and-overflow.html
当MySQL将值存储在数据列之外时 列数据类型的允许范围,结果取决于 当时有效的SQL模式
如果启用了严格的SQL模式,MySQL会拒绝超出范围的值 有错误,插入失败,按照SQL 标准。
如果没有启用限制模式,MySQL会将值剪辑到 范围的适当端点并存储结果值 代替。
因此,这意味着你应该设置必要的sql模式,当发生超出范围的错误时,该模式不会失败。
没有关于此的配置参数。
同样问题的解决方案,我们可以看到here表示禁用STRICT_TRANS_TABLES
和STRICT_ALL_TABLES
模式可以解决您的问题。