Длинное целое преобразуется при вставке в более короткий столбец, а не усечен. Зачем? Какова формула?

У меня есть столбец типа 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 ?
Почему он не уселся?
Каков механизм этого преобразования, и может ли полученное число быть вычислено с помощью некоторой формулы?


Я не ищу решения. Я просто хочу понять конкретный номер.

Solutions Collecting From Web of "Длинное целое преобразуется при вставке в более короткий столбец, а не усечен. Зачем? Какова формула?"

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

Целочисленное переполнение задает максимальное допустимое число в БД как

 2147483647 

Таким образом, вам нужен bigint данных bigint для хранения большего целого числа

Как и почему 715988985123857отвернуться в 2147483647?
Почему он не уселся?
Каков механизм этого преобразования, и может ли полученное число быть вычислено с помощью некоторой формулы?

Поведение зависит от настройки MySQL Strict SQL Mode :

Строгий режим контролирует, как MySQL обрабатывает недопустимые или отсутствующие значения в операторах смены данных, таких как INSERT или UPDATE.

В руководстве MySQL есть глава, объясняющая, как MySQL обрабатывает значения вне диапазона: Обработка вне диапазона и переполнения :

[…] Если не разрешены ограничительные режимы, MySQL скопирует значение в соответствующую конечную точку диапазона и вместо этого сохранит результирующее значение.

В случае типа Integer максимальное значение:

  • 2147483647 для подписанного типа
  • 4294967295 для неподписанного типа

Поскольку ваш запрос не выдавал ошибку, но вместо этого столбец обновлялся с максимально допустимым значением, вы можете предположить, что Strict SQL Mode не включен на вашем сервере. Вы можете проверить, выполнив:

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

Ни один из них не будет содержать значения STRICT_TRANS_TABLES или STRICT_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" 

… и на основе этого определяют допустимый предел.

Non-SQL? Валидация данных (серверная и клиентская) – это решение.

Ну, насколько я знаю, это не имеет ничего общего с PHP, bcx.

  • Если PHP встречает число за пределами целочисленного типа, оно будет интерпретироваться как float.
  • Кроме того, операция, которая приводит к числу за пределами целочисленного типа, вместо этого возвращает float.

Таким образом, функциональность SQL изменит значение.