2013-07-26 4 views
1

У меня вопрос о MySQL, сравнивающий разные типы данных. Скажем, у меня есть следующая таблица: MySQL: целое число для сравнения типов строк в выражении WHERE

CREATE TABLE `test`( 
    `value` VARCHAR(100) 
); 

Затем я вставить некоторые данные:

INSERT INTO test VALUES ('2XV4F2J'); 
INSERT INTO test VALUES ('123456'); 

Теперь, если я запустить простой запрос на выборку:

SELECT * FROM test WHERE `value` = 2 

Я знаю сравнения различных типов, поэтому в этом случае все должно сравниваться как «поплавки» в соответствии с документацией. Так, как и ожидалось, я получаю результат:

2XV4F2J 

Однако при попытке выполнить запрос обновления

UPDATE test SET `value` = 'some other value' WHERE `value` = 2 

Я получаю следующее сообщение об ошибке:

Error Code: 1292 
Truncated incorrect DOUBLE value: '2XV4F2J' 

Что мне делать не понимаю, почему я получаю ошибку только при запуске запроса UPDATE. Я бы ожидал получить ту же ошибку во время SELECT.

+0

я пытается ваш случай в сервере установлен 5.1, он работает в обоих выбирать и обновлять операторы. какие у вас настройки env? – hago

+0

У меня есть MySql 5.5.24 и sql-mode = TRADITIONAL – Andy

ответ

4

Это конкретное поведение базы данных обрабатывается так называемый «режим SQL», скорее всего, ваш MySQL Session имеет «STRICT_TRANS_TABLES» набор, вы можете проверить это с помощью: SELECT @@session.sql_mode;, смотрите пример вывода ниже:

mysql> SELECT @@session.sql_mode; 
+--------------------------------------------+ 
| @@session.sql_mode       | 
+--------------------------------------------+ 
| STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION | 
+--------------------------------------------+ 
1 row in set (0.00 sec) 

Чтобы объяснить, что каждый режим подробно будет немного недоступен, но чтобы сделать что-то коротким, в режиме STRICT_TRANS_TABLES будет отменена инструкция DML. Это необходимо для обеспечения целостности базы данных. Это означает, что вы не можете уничтожить целостность данных с помощью UPDATES/INSERTS, коротко говоря: «В случае DML предупреждения обрабатываются как ошибки». В случае операторов SELECT не существует опасности уничтожения целостности вашей базы данных, поэтому в этом режиме появляется предупреждение, если вы выполняете SELECT, но данные преобразуются в соответствующее значение. Это означает, что программист должен гарантировать достоверность извлеченных данных.

Чтобы вернуться к приведенному выше примеру, вы можете отключить строгий режим для своей сессии на set sql_mode='';, после этого ваш UPDATE будет работать с тем же предупреждением, что и в SELECT из вашего примера.

Важно: Внимательно прочитайте и уясните следующие части MySQL-Docs: Server SQL Modes, прежде чем вы даже осмеливаются возиться Arround с режимом SQL вашего сервера/сессии. Это может привести к тому, что ваша база данных будет непоследовательна, если вы и ваши разработчики не поймете в деталях, что они делают. Как указано выше, вы можете полностью выполнить свою задачу, чтобы гарантировать согласованность данных. Я бы настоятельно советовал, что вы позволили СУБД выполнять эту работу!

Ниже тестовой сессии с помощью приведенного выше примера:

mysql> CREATE TABLE `test`( 
    -> `value` VARCHAR(100) 
    ->); 
Query OK, 0 rows affected (0.06 sec) 

mysql> INSERT INTO test VALUES ('2XV4F2J'); 
Query OK, 1 row affected (0.00 sec) 

mysql> INSERT INTO test VALUES ('123456'); 
Query OK, 1 row affected (0.00 sec) 

mysql> SELECT * FROM test WHERE `value` = 2; 
+---------+ 
| value | 
+---------+ 
| 2XV4F2J | 
+---------+ 
1 row in set, 1 warning (0.00 sec) 

mysql> UPDATE test SET `value` = 'some other value' WHERE `value` = 2; 

ERROR 1292 (22007): Truncated incorrect DOUBLE value: '2XV4F2J' 

Теперь отключить строгий режим и сделать обновление:

mysql> set sql_mode=''; 
Query OK, 0 rows affected (0.00 sec) 

mysql> UPDATE test SET `value` = 'some other value' WHERE `value` = 2; 
Query OK, 1 row affected, 1 warning (0.01 sec) 
Rows matched: 1 Changed: 1 Warnings: 1 

mysql> show warnings; 
+---------+------+---------------------------------------------+ 
| Level | Code | Message          | 
+---------+------+---------------------------------------------+ 
| Warning | 1292 | Truncated incorrect DOUBLE value: '2XV4F2J' | 
+---------+------+---------------------------------------------+ 
1 row in set (0.00 sec) 

mysql> select * from test; 
+------------------+ 
| value   | 
+------------------+ 
| some other value | 
| 123456   | 
+------------------+ 
2 rows in set (0.00 sec) 
+0

+1 Хороший ответ. – peterm

Смежные вопросы