php mysql integer iec10967

php - El entero largo se transforma cuando se inserta en una columna más corta, no truncada. ¿Por qué? ¿Cuál es la fórmula?



mysql integer (3)

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

El desbordamiento entero establecerá el número máximo permitido en la base de datos como

2147483647

Por lo tanto, necesita un bigint datos bigint para almacenar un entero más grande

Tengo una columna de tipo integer con longitud 10:

`some_number` int(10) unsigned NOT NULL

En esta columna, inserto un número que es demasiado largo:

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

Cuando miro lo que hay en la tabla, el número ahora es:

2147483647

¿Cómo y por qué el 715988985123857 convirtió en 2147483647 ?
¿Por qué no se truncó?
¿Cuál es el mecanismo detrás de esta transformación y se puede calcular el número resultante con alguna fórmula?

No estoy buscando una solución. Solo quiero entender el número específico.


Hasta donde yo sé, no tiene nada que ver con PHP, bcx.

  • Si PHP encuentra un número más allá de los límites del tipo entero, se interpretará como un flotante.
  • Además, una operación que da como resultado un número más allá de los límites del tipo entero devolverá una flotación en su lugar.

Entonces será la funcionalidad de SQL la que cambie el valor.


¿Cómo y por qué el 715988985123857virtió en 2147483647?
¿Por qué no se truncó?
¿Cuál es el mecanismo detrás de esta transformación y se puede calcular el número resultante con alguna fórmula?

El comportamiento depende de la configuración de MySQL Strict SQL Mode :

El modo estricto controla la forma en que MySQL maneja los valores inválidos o perdidos en las instrucciones de cambio de datos como INSERT o UPDATE.

Hay un capítulo en el manual de MySQL que explica cómo MySQL maneja los valores fuera de rango: fuera de rango y manejo de desbordamiento :

[...] Si no se habilitan modos restrictivos, MySQL recorta el valor al punto final apropiado del rango y almacena el valor resultante en su lugar.

En el caso de Integer Type , el valor máximo es:

  • 2147483647 para tipo firmado
  • 4294967295 para tipo sin firmar

Como su consulta no arrojó un error, sino que la columna se actualizó con el valor máximo permitido, puede suponer que el modo SQL estricto no está habilitado en su servidor. Puede verificarlo ejecutando:

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

Ninguno de ellos contendrá STRICT_TRANS_TABLES ni STRICT_ALL_TABLES valores (más sobre los valores en MySQL man: sql_mode ).
Tome este ejemplo para probar los diferentes comportamientos entre modos:

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)

En resumen, con el modo estricto, el valor fuera de rango produce un error, sin - el valor se ajusta al límite permitido y se produce una advertencia.

En cuanto a esta pregunta:

¿El número resultante se puede calcular con alguna fórmula?

No conozco ninguna fórmula simple y pura de MySQL. Debería verificar el tipo de datos y la longitud:

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"

... y en base a eso determinar el límite permitido.

No sql? La validación de datos (del lado del servidor y del lado del cliente) es la solución.