我有一个关于 MySQL 比较不同数据类型的问题。假设我有一个下表:
CREATE TABLE `test`(
`value` VARCHAR(100)
);
然后我插入一些数据:
INSERT INTO test VALUES ('2XV4F2J');
INSERT INTO test VALUES ('123456');
现在,如果我运行一个简单的选择查询:
SELECT * FROM test WHERE `value` = 2
我知道不同类型的比较,因此在这种情况下,根据文档,所有内容都应作为“ float ”进行比较。所以正如预期的那样,我得到了结果:
2XV4F2J
但是当我尝试运行更新查询时
UPDATE test SET `value` = 'some other value' WHERE `value` = 2
我收到以下错误消息:
Error Code: 1292
Truncated incorrect DOUBLE value: '2XV4F2J'
我不明白的是为什么我只在运行 UPDATE 查询时才收到错误。我预计在 SELECT 期间也会遇到同样的错误。
最佳答案
数据库的这种特殊行为由所谓的“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='';
关闭 session 的严格模式,之后您的 UPDATE 将产生与您的 SELECT 中相同的警告示例。
重要: 仔细阅读并理解 MySQL-Docs 的以下部分:Server SQL Modes,然后再敢乱用服务器/ session 的 SQL 模式。这可能会导致您的数据库不一致,除非您和您的开发人员不非常深入地了解他们在做什么。如上所述,保证数据一致性完全取决于您。我强烈建议您让 DBMS 来完成这项工作!
使用上面的示例查看下面的测试 session :
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)
关于MySQL:WHERE 子句中的整数到字符串类型比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17874921/