У меня есть база данных MySQL, которая показывает поведение, которое я хотел бы понять лучше. Почему я могу искать значение CHAR, вставленное в поле INT? У меня есть поле, которое имеет тип INT, но это, кажется, может записать символьные значения, как это возможно?
Я пытался изолировать проблему путем создания базы данных с INT и VARCHAR. Я вставил "TEST1" в значение INT, но все еще смог искать строку с помощью значения Строки идентификатора. Предупреждение после вставки строки в Значение идентификатора
| Warning | 1366 | Incorrect integer value: 'TEST1' for column 'ID' at row 1 |
но я все еще смог искать то значение. Я хотел бы понять, почему это возможно.
mysql> CREATE TABLE test1(ID int, DATA varchar(255));
Query OK, 0 rows affected (0.18 sec)
mysql> INSERT INTO test1(ID,DATA) VALUES('TEST1', 'TEST1');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> SELECT * FROM test1 WHERE ID = 'TEST1';
+------+-------+
| ID | DATA |
+------+-------+
| 0 | TEST1 |
+------+-------+
1 row in set, 1 warning (0.00 sec)
Предупреждение после ВЫБОРА
| Warning | 1366 | Incorrect integer value: 'TEST1' for column 'ID' at row 1 |
но результаты все еще корректны.
Я ожидал бы, что ВЫБОР выше найдет 0 результатов, но дело не в этом, почему?
ОТВЕТ:
С помощью ответа Asaph ниже и комментариев Pekka ответ кажется очевидным теперь.
Во время ВСТАВКИ MySQL не удалось вставить символьное значение в поле INT, таким образом, это заменило его 0. То же самое произошло во время ВЫБОРА поэтому в действительности, я делал ВЫБОР на идентификаторе = 0 для любого символьного значения, которое я искал.
mysql> SELECT * FROM test1 WHERE ID = 'SOMETHING_OTHER_THAN_TEST1';
+------+-------+
| ID | DATA |
+------+-------+
| 0 | TEST1 |
+------+-------+
1 row in set, 1 warning (0.00 sec)
Это возвращает тот же результат как мой начальный выбор, так как он действительно работает как
SELECT * FROM test1 WHERE ID = 0;
в бэкенде.
В любом случае лучшая практика, кажется, для использования sql_mode = 'STRICT_ALL_TABLES' в конфигурационном файле MySQL или самом SQL-операторе.
Для включения STRICT_ALL_TABLES для всех SQL-запросов на сервере MySQL, необходимо добавить следующее под [mysqld] заголовком в my.cnf файле, который обычно располагается в/etc/my.cnf
[mysqld]
...
...
...
sql-mode=STRICT_ALL_TABLES
Вы можете предотвратить вставку бессмысленных значений в первую очередь, установив режим STRICT_ALL_TABLES
, который можно установить в my.cnf
или "на лету":
mysql> SET sql_mode = 'STRICT_ALL_TABLES';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE test1(ID int, DATA varchar(255));
Query OK, 0 rows affected (0.42 sec)
mysql> INSERT INTO test1(ID,DATA) VALUES('TEST1', 'TEST1');
ERROR 1264 (22003): Out of range value adjusted for column 'ID' at row 1
mysql> SELECT * FROM test1 WHERE ID = 'TEST1';
Empty set (0.00 sec)
mysql> SELECT * FROM test1;
Empty set (0.00 sec)