3

我有一列integer长度为 10 的类型:

`some_number` int(10) unsigned NOT NULL

在此列中,我插入了一个太长的数字:

$some_number = 715988985123857;
$query = "INSERT INTO this_table SET some_number = ?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param('i', $some_number);
$stmt->execute();

当我查看表格中的内容时,现在的数字是:

2147483647

如何以及为什么715988985123857变成2147483647?
为什么没有被截断?
这种转换背后的机制是什么,可以用一些公式计算得到的数字吗?


我不是在寻找解决方案。我只是想了解具体的数字。

4

3 回答 3

4

http://dev.mysql.com/doc/refman/5.0/en/integer-types.html

整数溢出会将数据库中允许的最大数量设置为

2147483647

所以你需要bigint 数据类型来存储更大的整数

于 2014-05-08T18:56:06.873 回答
1

715988985123857 如何以及为什么变成 2147483647?
为什么没有被截断?
这种转换背后的机制是什么,可以用一些公式计算得到的数字吗?

该行为取决于 MySQL Strict SQL Mode设置:

严格模式控制 MySQL 如何处理数据更改语句(如 INSERT 或 UPDATE)中的无效或缺失值。

MySQL手册中有一章解释了MySQL如何处理超出范围的值:超出范围和溢出处理

[...] 如果没有启用限制模式,MySQL 会将值剪辑到范围的适当端点并存储结果值。

Integer Type的情况下,最大值为:

  • 2147483647 用于签名类型
  • 无符号类型为 4294967295

由于您的查询没有引发错误,而是使用最大允许值更新了该列,因此您可以假设您的服务器上未启用严格 SQL 模式。您可以通过运行来验证:

SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;

它们都不包含STRICT_TRANS_TABLESnorSTRICT_ALL_TABLES值(更多关于 MySQL man 中的值:)sql_mode
以这个例子来测试模式之间的不同行为:

mysql> create table test_sql_mode(id int);
mysql> set sql_mode = 'STRICT_TRANS_TABLES';
mysql> SELECT @@SESSION.sql_mode;
+---------------------+
| @@SESSION.sql_mode  |
+---------------------+
| STRICT_TRANS_TABLES |
+---------------------+
1 row in set (0.00 sec)

mysql> insert into test_sql_mode(id) value(123456789123456789);
ERROR 1264 (22003): Out of range value for column 'id' at row 1

mysql> select * from test_sql_mode;
Empty set (0.00 sec)

mysql> set sql_mode = '';
mysql> SELECT @@SESSION.sql_mode;
+--------------------+
| @@SESSION.sql_mode |
+--------------------+
|                    |
+--------------------+
1 row in set (0.00 sec)

mysql> insert into test_sql_mode(id) value(123456789123456789);
Query OK, 1 row affected, 1 warning (0.05 sec)

mysql> show warnings;
+-------+------+---------------------------------------------+
| Level | Code | Message                                     |
+-------+------+---------------------------------------------+
| Error | 1264 | Out of range value for column 'id' at row 1 |
+-------+------+---------------------------------------------+

mysql> select * from test_sql_mode;
+------------+
| id         |
+------------+
| 2147483647 |
+------------+
1 row in set (0.00 sec)

简而言之,在严格模式下,超出范围的值会产生错误,而没有 - 值会调整到允许的限制并产生警告。


至于这个问题:

可以用一些公式计算得到的数字吗?

我不知道任何简单而纯粹的 MySQL 公式。您必须检查数据类型和长度:

select data_type, numeric_precision, numeric_scale
from information_schema.columns
where table_schema = "test_database"
and table_name = "test_sql_mode"
and column_name = "id"

...并基于此确定允许的限制。

非sql?数据验证(服务器端和客户端)是解决方案。

于 2014-10-22T11:20:04.643 回答
0

好吧,据我所知,它与 PHP、bcx 没有任何关系。

  • 如果 PHP 遇到超出整数类型范围的数字,它将被解释为浮点数。
  • 此外,导致数字超出整数类型范围的操作将改为返回浮点数。

因此,改变值的将是 SQL 的功能。

于 2014-05-08T19:03:42.627 回答