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 来避免这个问题。
相关文章:
MySQL 案例:update set 和 and 的坑
问题描述 最近碰到到一个奇怪的问题,update 语句执行没有报错,但是没有更新数据,具体有问题的语句类似于如下形式: update test.stu set cname 0 and math 90 and his 80 where id 100; 复制 原因分析 直观上看ÿ…...
VSCode remote-ssh 连接远端服务器失败
系统 Mac os Intel处理器 描述 该问题在上午时还没有,下午突然毫无征兆的发生,当时没有更新vscode,没有更新插件。 分析 网上对于该问题的答案多是说磁盘空间不够vscode不能下载相应插件,我所遇到的并不是这种情况。报的错误多是…...
通达信动量线MTM指标原理详解及MTM底背离选股公式
MTM指标(动量线指标)用于衡量价格的动量和趋势,以判断未来价格的变化。计算方法很简单,用当前价格减去一段时间(通常为12日)前的价格,计算得到的差值的正负和大小,可以判断可能的趋势…...
汇编-DUP操作符
DUP操作符使用整数表达式作为计数器, 为多个数据项分配存储空间。 在为字符串或数组分配存储空间时,这个操作符尤其有用,并且可以使用初始化或非初始化数据: .data BYTE 20 DUP(0) ;20个字节,都等于0 BYTE 20 …...
2311C++抽象工厂
1,为啥需要工厂设计模式?工厂设计模式可解决什么问题? 先看一下示例,多态示例. #include <iostream> using namespace std; class Shape { public:Shape() { }virtual void drawShape(){cout << "base draw shape" << endl;} }; class Rectang…...
Lavarel定时任务的使用
系统为window 执行命令(执行一次命令只会根据当前时间运行一次定时任务) php artisan schedule:run创建一个任务类(在Jobs文件夹下面) <?phpnamespace App\Jobs;use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contract…...
Java开发者的网络安全指南(二)
目录 一、加密和数据保护 二、身份验证和授权 三、Web应用程序安全 四、安全编码实践 五、网络防火墙和入侵检测系统 六、日志和监视 七、漏洞管理 八、安全教育和培训 九、结论 介绍: 简要说明网络安全的重要性和为什么Java开发者需要关注它。 一、加密…...
Python基础学习016__UnitTest
# UnitTest是python自带的一个单元测试框架,不需要额外安装 # 也是自动化脚本执行框架,使用UnitTest来管理,运行多个框架 # 为什么使用:能够组织多个用例去执行.提供了丰富的断言方法,能够生成测试报告 # 核心要素: # Testcase:测试用例:这个测试用例是UnitTest的组成部分,不是…...
一物一码需求,标签制作功能轻松解决
许多行业存在为人员、物品、设备等做一物一码标签的需求,可使用草料标签制作功能。直接选择标签样式,填入数据,即可批量生成标签,还可批量排版,更易落地。还可保存标签样式,后续多次复用样式,批…...
【Linux】七、基础IO
预备知识 文件 属性(本质上也是数据)内容; 文件的所有操作大致有两种,对内容的操作,和对属性的操作; 文件在磁盘中放置,磁盘是硬件,只有操作系统可以真正的访问磁盘;C\C…...
Elasticsearch语法之Term query不区分大小写
设置关键词是否区分大小写 说明:case_insensitive是term的可选参数,默认为false,表示关键词区分大小写,设置为true表示关键词不区分大小写。该参数在7.10.0开始有效 需求:分别使用关键词"iphone"和"I…...
远程管理SSH服务
一、搭建SSH服务 1、关闭防火墙与SELinux # 关闭firewalld防火墙 # 临时关闭 systemctl stop firewalld # 关闭开机自启动 systemctl disable firewalld # 关闭selinux # 临时关闭 setenforce 0 # 修改配置文件 永久关闭 vim /etc/selinux/config SELINUXdisabled 2、配置…...
Linux 实现原理 — NUMA 多核架构中的多线程调度开销与性能优化
前言 NOTE:本文中所指 “线程” 均为可执行调度单元 Kernel Thread。 NUMA 体系结构 NUMA(Non-Uniform Memory Access,非一致性存储器访问)的设计理念是将 CPU 和 Main Memory 进行分区自治(Local NUMA node&#x…...
Oracle锁处理
背景: 随着数据库版本不断迭代更新, v$session 视图的内容越来越丰富,可以直接使用blocking_session、blocking_instance、final_blocking_instance和final_blocking_session字段进行定位。对于锁层次的排查可以重复查询v$session来确定&am…...
持续集成交付CICD:安装Jenkins Slave(从节点)
目录 一、实验 1.安装Jenkins Slave(从节点) 二、问题 1.salve节点启动jenkins报错 2.终止命令行后jenkins从节点状态不在线 一、实验 1.安装Jenkins Slave(从节点) (1)查看jenkins版本 Version 2.…...
Dart(一):Dart入门
Dart入门 Dart安装创建项目安装依赖(以http为例)依赖库查询地址添加依赖编写运行示例 dart常用命令引用核心库、自定义库、第三方库数据类型Numbers (int, double)Strings (String)Booleans (bool)Lists (List)Maps (Map)Sets (Set)Null (null)Records (…...
[动态规划] (十一) 简单多状态 LeetCode 面试题17.16.按摩师 和 198.打家劫舍
[动态规划] (十一) 简单多状态: LeetCode 面试题17.16.按摩师 和 198.打家劫舍 文章目录 [动态规划] (十一) 简单多状态: LeetCode 面试题17.16.按摩师 和 198.打家劫舍题目分析题目解析状态表示状态转移方程初始化和填表顺序 代码实现按摩师打家劫舍 总结 注:本题与…...
【EI会议投稿】第三届计算机、人工智能与控制工程国际学术会议 (CAICE 2024)
The 3rd International Conference on Computer, Artificial Intelligence and Control Engineering (CAICE 2024) 第三届计算机、人工智能与控制工程国际学术会议 第三届计算机、人工智能与控制工程国际学术会议(CAICE 2024)将于2024年1月26-28日在西…...
python 之 列表推导式
文章目录 基本结构示例 1:将列表中的元素乘以 2 添加条件判断示例 2:筛选出偶数并加倍 嵌套列表推导式示例 3:生成九九乘法表 使用条件表达式示例 4:根据条件返回不同的值 镶嵌使用详细介绍基本结构示例生成二维数组多重筛选和操作…...
【左程云算法全讲2】链表、栈、队列、递归、哈希表和有序表
系列综述: 💞目的:本系列是个人整理为了秋招面试的,整理期间苛求每个知识点,平衡理解简易度与深入程度。 🥰来源:材料主要源于左程云算法课程进行的,每个知识点的修正和深入主要参考…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
