【MYSQL】记录 MYSQL UPDATE AND 产生的问题

记录 MYSQL UPDATE AND 产生的问题

基于 Server version: 8.0.16 MySQL Community Server - GPL 版本

表结构数据初始化

-- ----------------------------
-- Table structure for t_user
-- ----------------------------
CREATE TABLE `t_user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (1, 'a', '123');
INSERT INTO `t_user` VALUES (2, 'b', '123');
INSERT INTO `t_user` VALUES (3, 'c', '123');

查看数据

mysql> select * from t_user;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | a        | 123      |
|  2 | b        | 123      |
|  3 | c        | 123      |
+----+----------+----------+
3 rows in set (0.00 sec)

如果想要将 id=1 的记录更新成 username='e' password='456' 正常是这么写

update t_user set username = 'e', `password` = '456' where id = 1;

但是如果手抽了写成

update t_user set username = 'e' and `password` = '2' where id = 1;  -- 1

> 1292 - Truncated incorrect DOUBLE value: 'e'

一个 ,and 的区别导致了不同的结果,并且将错就错将上面的 UPDATE AND 改写下

update t_user set `password` = '456' and username = 'e' where id = 1; -- 2

> Affected rows: 1

结果更新成功了,但是并没有按照预期,而是将 id=1password 改为了 0

mysql> select * from t_user;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | a        | 0        |
|  2 | b        | 123      |
|  3 | c        | 123      |
+----+----------+----------+
3 rows in set (0.00 sec)

再来个变形

update t_user set `password` = '456' and username = 'a' where id = 1; -- 3

> Affected rows: 1

与上条对比只是改变了username的值,还是更新成功了,但是 password 被置为了 1

mysql> select * from t_user;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | a        | 1        |
|  2 | b        | 123      |
|  3 | 123      | c        |
+----+----------+----------+
3 rows in set (0.00 sec)

结论:

如果将 , 写成了 and 其实是对 set 后的第一个字段进行赋值,而后面的and条件作为逻辑运算,换种写法更明了

update t_user set username = ('e' and `password` = '2') where id = 1;  -- 1
update t_user set `password` = ('456' and username = 'e') where id = 1; -- 2
update t_user set `password` = ('456' and username = 'a') where id = 1; -- 3

对于第一种情况,e 不能作为逻辑运算的条件所以报 Truncated incorrect DOUBLE value: 'xxx'

对于第二种情况,456 被当成 true (1), username = 'e' 不成立,所以右边的条件为 false (0),1 and 0 => 0 所以password 被置为 0

对于第三种情况,456 被当成 true (1), username = 'a' 成立,所以右边的条件为 true (1),1 and 1 => 1 所以password 被置为 1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章