2013-07-26 98 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服務器的情況下,它工作在兩個選擇並更新語句。你的環境設置是什麼? – hago

+0

我有MySql 5.5.24和sql-mode = TRADITIONAL – Andy

回答

4

數據庫的這種特殊的行爲是由所謂的「SQL模式」處理,很可能你的MySQL會話「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,然後您甚至不敢亂動服務器/會話的SQL模式。這可能會導致您的數據庫不一致,除非您和您的開發人員不深入瞭解他們正在做的事情。如上所述,它完全由您來保證數據的一致性。我強烈建議您讓DBMS完成這項工作!

看到測試會話下面用你上面的例子:

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