Mam bazę danych MySQL, która wyświetla zachowanie, które chciałbym lepiej zrozumieć. Dlaczego mogę wyszukać wartość CHAR wstawioną do pola INT? Mam pole, które jest typu INT, ale wydaje się być w stanie rejestrować wartości znaków, jak to możliwe?Dlaczego można wstawiać znaki do pola int MySQL?
Próbowałem wyizolować problem, tworząc bazę danych z INT i VARCHAR. Wstawiłem "TEST1" do wartości INT, ale wciąż byłem w stanie wyszukać wiersz za pomocą wartości ciągu ID. Ostrzeżenie po wstawieniu ciągu znaków do wartości identyfikatora to
| Warning | 1366 | Incorrect integer value: 'TEST1' for column 'ID' at row 1 |
, ale wciąż byłem w stanie wyszukać tę wartość. Chciałbym zrozumieć, dlaczego jest to możliwe.
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)
Ostrzeżenie po SELECT
| Warning | 1366 | Incorrect integer value: 'TEST1' for column 'ID' at row 1 |
ale wyniki są nadal poprawne.
Spodziewam się, że powyższy SELECT znajdzie 0 wyników, ale tak nie jest, dlaczego?
ODPOWIEDŹ:
Dzięki za odpowiedź Asafa poniżej i komentarze Pekka za odpowiedź wydaje się oczywista teraz.
Podczas INSERT, MySQL nie wstawił wartości znaku do pola INT, więc zastąpił ją 0. To samo stało się podczas SELECT, więc w efekcie robiłem SELECT na ID = 0 dla dowolnej wartości znaku I szukał.
mysql> SELECT * FROM test1 WHERE ID = 'SOMETHING_OTHER_THAN_TEST1';
+------+-------+
| ID | DATA |
+------+-------+
| 0 | TEST1 |
+------+-------+
1 row in set, 1 warning (0.00 sec)
która zwraca ten sam wynik jak mój początkowy wybierz ponieważ to naprawdę działa jak
SELECT * FROM test1 WHERE ID = 0;
w backend.
W każdym przypadku najlepszą praktyką wydaje się używanie sql_mode = 'STRICT_ALL_TABLES' w pliku konfiguracyjnym MySQL lub samej instrukcji SQL.
Aby włączyć STRICT_ALL_TABLES dla wszystkich zapytań SQL na serwerze MySQL trzeba dodać następujące pod [mysqld] nagłówka w pliku my.cnf który zazwyczaj znajduje się w /etc/my.cnf
[mysqld]
...
...
...
sql-mode=STRICT_ALL_TABLES
Zauważyłeś MySQL wydane '1 warning' podczas wykonywania zapytanie .. Może dobrze wiedzieć, co to jest ...? – Romain
Zaktualizowałem pytanie z wynikami ostrzeżenia, ale wynik jest nadal poprawny, o to właśnie się zastanawiam. –