MySQL 案例:update set 和 and 的坑

问题描述

最近碰到到一个奇怪的问题,update 语句执行没有报错,但是没有更新数据,具体有问题的语句类似于如下形式:

update test.stu set cname = '0' and math = 90 and his = 80 where id = 100;

复制

原因分析

直观上看,这个 update 语句的语法是有问题的,正常更新多列数据的语法应该是用逗号,类似于如下形式:

update test.stu set cname = '0',math = 90,his = 80 where id = 100;

复制

直接用 and 第一反应其实是会报语法错误,不太像是能正常执行的。那么基于云数据库 MySQL,实际构造一个简单的场景,尝试复现一下这个问题。

SQL 语句如下:

CREATE TABLE `stu` (`id` int(11) NOT NULL,`sname` varchar(16) NOT NULL,`cname` varchar(8) DEFAULT NULL,`math` int(11) NOT NULL,`eng` int(11) DEFAULT NULL,`his` int(11) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;insert into stu values(100,'sam','0',90,88,83);
insert into stu values(101,'jhon','1',97,82,81);
insert into stu values(102,'mary','2',87,89,92);
insert into stu values(103,'adam','2',87,89,92);

复制

然后分别试一试正常的 update 语句和使用 and 的 update 语句,看一下实际的运行结果:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> update test.stu set cname = '0' and math = 90 and his = 80 where id = 100;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0mysql> select * from stu;
+-----+-------+-------+------+------+------+
| id  | sname | cname | math | eng  | his  |
+-----+-------+-------+------+------+------+
| 100 | sam   | 0     |   90 |   88 |   83 |
| 101 | jhon  | 1     |   97 |   82 |   81 |
| 102 | mary  | 2     |   87 |   89 |   92 |
| 103 | adam  | 2     |   87 |   89 |   92 |
+-----+-------+-------+------+------+------+
4 rows in set (0.00 sec)mysql> update test.stu set cname = '0',math = 90,his = 80 where id = 100;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from stu;
+-----+-------+-------+------+------+------+
| id  | sname | cname | math | eng  | his  |
+-----+-------+-------+------+------+------+
| 100 | sam   | 0     |   90 |   88 |   80 |
| 101 | jhon  | 1     |   97 |   82 |   81 |
| 102 | mary  | 2     |   87 |   89 |   92 |
| 103 | adam  | 2     |   87 |   89 |   92 |
+-----+-------+-------+------+------+------+
4 rows in set (0.00 sec)mysql> rollback;
Query OK, 0 rows affected (0.01 sec)mysql>

复制

可以看到这两个语句确实都不会报错,且带 and 的 update 语句匹配到了具体的行(Rows matched: 1),但是没有修改数据(Changed: 0),标准语法下的 update 语句倒是正常修改了数据。

由此可见,MySQL 在语法上,并不认为 and 这个用法是错误的,那么说明 MySQL 用另外的方式“解读”了这个语句。最容易想到的,就是 MySQL 是不是在 set 的时候,把 and 解释成了逻辑运算符,而不是英文意义上的“和”?而且 cname 的取值本来就是 0,也符合数据库处理 bool 数据时的行为(用 0 和 1 代替 False 和 True)。

验证起来很简单,换个 cname 不为 0 的数据 update 一下就可以了:

mysql> select * from stu;
+-----+-------+-------+------+------+------+
| id  | sname | cname | math | eng  | his  |
+-----+-------+-------+------+------+------+
| 100 | sam   | 0     |   90 |   88 |   83 |
| 101 | jhon  | 1     |   97 |   82 |   81 |
| 102 | mary  | 2     |   87 |   89 |   92 |
| 103 | adam  | 2     |   87 |   89 |   92 |
+-----+-------+-------+------+------+------+
4 rows in set (0.00 sec)mysql> begin;update test.stu set cname = '0' and math = 90 and his = 80 where id = 101;
Query OK, 0 rows affected (0.00 sec)Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from stu;
+-----+-------+-------+------+------+------+
| id  | sname | cname | math | eng  | his  |
+-----+-------+-------+------+------+------+
| 100 | sam   | 0     |   90 |   88 |   83 |
| 101 | jhon  | 0     |   97 |   82 |   81 |
| 102 | mary  | 2     |   87 |   89 |   92 |
| 103 | adam  | 2     |   87 |   89 |   92 |
+-----+-------+-------+------+------+------+
4 rows in set (0.00 sec)mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

复制

从结果来看,MySQL 修改 cname 的值为 0,说明确实是当成逻辑运算符来处理了,仔细分析这个语句,会发现 MySQL 按照如下方式来处理:

set cname = ('0' and math = 90 and his = 80)

复制

math 和 his 的取值是根据 where 条件筛选的行来决定的,实际对应到上面测试的场景,会变成如下的逻辑判断:

'0' and 97 = 90 and 81 = 80

复制

PS:需要注意,即便是字符型的数据 0,也会被当做 False。

解决方案

目前并不能通过 sql_mode 或者其他参数的形式来阻止这种带 and 的 update 语句,因此这一类问题的隐蔽性比较强。建议在开发的时候,利用封装好的框架,或者加强代码或者 SQL review 来避免这个问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/132134.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从行车记录仪恢复已删除/丢失视频的方法

“我的车里有行车记录仪。几天前,当我下班回家时,一辆卡车不知从哪里冒出来撞向了我。我们的两辆车都损坏了,但幸运的是,没有人受伤。我曾与卡车司机就修理我的汽车进行过会面,但他说我有错。我需要查看我的行车记录仪…

【每日一题】移除链表元素(C语言)

移除链表元素,链接奉上 目录 思路:代码实现:链表题目小技巧: 思路: 在正常情况: 下我们移除链表元素时,需要该位置的前结点与后节点, 在特别情况时: 例如 我们发现&…

[算法日志]图论: 深度优先搜索(DFS)

[算法日志]图论: 深度优先搜索(DFS) 深度优先概论 ​ 深度优先搜索算法是一种遍历图这种数据结构的算法策略,其中心思想是朝图节点的一个方向不断跳转,当该节点无下一个节点或所有方向都遍历完时,便回溯朝上一个节点的另一个方向…

基于金枪鱼群算法的无人机航迹规划-附代码

基于金枪鱼群算法的无人机航迹规划 文章目录 基于金枪鱼群算法的无人机航迹规划1.金枪鱼群搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要:本文主要介绍利用金枪鱼群算法来优化无人机航迹规划。 …

数据库性能优化(查询优化、索引优化、负载均衡、硬件升级等方面)

数据库性能优化是提升数据库系统整体性能和响应速度的一系列技术和策略。它可以通过多种方式来实现,包括优化查询语句、索引设计、硬件升级、负载均衡等手段。 合适的数据模型设计 正确的数据模型设计是性能优化的基石。合理的表结构和关系设计可以减少冗余数据&…

告别困惑!JS中‘==‘ 与 ‘===‘ 的真相大揭秘!

当谈到JavaScript中的""和""运算符时,有时候它们的区别可能让人感到困惑。尽管它们都用于比较值,但它们的行为有着重要的差异。在本文中,我们将解释""和""之间的区别,以及在实际编码中如…

vue项目npm install报错解决

一、报错信息 node-sass4.14.1 postinstall: node scripts/build.js 二、解决方式 (1)删除未成功安装的 node_modules 文件; (2)为 node-sass 单独设置镜像源; npm config set sass_binary_sitehttps:/…

项目级asp.net框架的LIMS实验室管理系统源码

LIMS可用于管理完整的实验程序,从样品登记到检验、校核、审核到最终批准报告,建立在过程质量控制的基础上,对检测流程进行有效全面的管理,对影响质量的人、机、料、法、环因素加以控制,同时为质量改进提供数据依据。进…

实时目标检测与跟踪:机器视觉的挑战与机遇

实时目标检测与跟踪是机器视觉领域的一个重要研究方向,它涉及到在视频或图像序列中准确地定位和跟踪多个目标对象。这个任务具有很高的挑战性,同时也带来了许多机遇。 挑战: 1. 复杂背景:目标检测与跟踪需要在复杂的背景中准确地…

187. 重复的DNA序列 --力扣 --JAVA

题目 DNA序列 由一系列核苷酸组成,缩写为 A, C, G 和 T.。 例如,"ACGAATTCCG" 是一个 DNA序列 。 在研究 DNA 时,识别 DNA 中的重复序列非常有用。 给定一个表示 DNA序列 的字符串 s ,返回所有在 DNA 分子中出现不止一次…

Cassandra介绍(一)

1.1. 概念 Apache Cassandra 是高度可扩展的,高性能的分布式 NoSQL 数据库。 Cassandra 旨在处理许 多商品服务器上的大量数据,提供高可用性而无需担心单点故障。 Cassandra 具有能够处理大量数据的分布式架构。 数据放置在具有多个复制因子的不同机器…

操作符、sed和awk

操作符: d 删除 s sed的替换功能,& s:替换字符串 c:整行替换 y:字符替换,替换前后的长度必须相同。 l&:转换小写的特殊符号,前面要加\转义符 u&:转换成大写的特殊…

Luminar Neo Mac/Windows中文版:引领AI图像编辑的革命性时代

Luminar Neo运用先进的AI技术,能够自动化地完成许多繁琐的编辑任务,如色彩校正、噪点消除、人脸识别等。这不仅大大提高了工作效率,同时也降低了对专业知识和技能的要求。无论你是专业摄影师,还是摄影爱好者,甚至是一个…

产品实习笔记——会员体系 积分体系

文章目录 引入会员体系1. 业务逻辑产品化2. 产品逻辑可视化2.1 成长值:会员等级的判断机制2.1.1 成长值的获得2.1.1 成长值的消耗 2.2 会员等级区间划分2.3 成长值风控体系2.4 会员权益2.4.1 普通会员权益2.4.2 阶梯式会员权益 积分体系有赞商城(会员体系…

数据可视化:折线图

1.初看效果 (1)效果一 (2)数据来源 2.JSON数据格式 其实JSON数据在JAVA后期的学习过程中我已经是很了解了,基本上后端服务器和前端交互数据大多是采用JSON字符串的形式 (1)JSON的作用 &#…

设计模式第一课-单例模式(懒汉模式和饿汉模式)

单例模式 个人理解:单例模式实际就是通过类加载的方式获取到一个对象,并且保证这个对象在使用中只有一个,不允许再次被创建 一、懒汉模式 1、懒汉模式的基础写法 代码解释: (1)、编写LazySingleton类的…

k8s、调度约束

Kubernetes 是通过 List-Watch **** 的机制进行每个组件的协作,保持数据同步的,每个组件之间的设计实现了解耦 用户是通过 kubectl 根据配置文件,向 APIServer 发送命令,在 Node 节点上面建立 Pod 和 Container。 APIS…

基于STC15单片机温度光照蓝牙传输-proteus仿真-源程序

一、系统方案 本设计采用STC15单片机作为主控器,液晶1602显示,DS18B20采集温度,光敏电阻采集光照、按键设置温度上下限,测量温度小于下限,启动加热,测量温度大于上限,启动降温。 二、硬件设计 …

开发知识点-PHP从小白到拍簧片

从小白到拍簧片 位异或运算(^ )引用符号(&)strlen() 函数base64_encode预定义 $_POST 变量session_start($array);操作符php 命令set_time_limit(7200)isset()PHP 命名空间(namespace)new 实例化类extends 继承 一个类使用另一个类方法error_reporti…

长短期神经网络LSTM的博文分类,长短期神经网络的原理分析

目录 背影 摘要 代码和数据下载:长短期神经网络LSTM的博文分类,长短期神经网络微博博文分类(代码完整,数据齐全)资源-CSDN文库 https://download.csdn.net/download/abc991835105/88498278 LSTM的基本定义 LSTM实现的步骤 长短期神经网络LSTM的博文分类,长短期神经网络微…