5.2 UPDATE 更新数据


5.2 UPDATE 更新数据

本节摘要:UPDATE 修改现有行的列值。本节讲 SET 改值、WHERE 限定范围、多列更新,以及"忘写 WHERE 全表更新"这个最危险的坑。

上手前先明确

阅读完本节,你应当能够:

  1. 写 UPDATE 语句改单列多列
  2. 用 WHERE 限定更新范围
  3. 用表达式更新(基于原值)
  4. 养成写 UPDATE 的安全习惯

概念脉络

一、基本语法

UPDATE 表名 SET 列 = 值 WHERE 条件;

SET 指定改哪列成什么值,WHERE 限定改哪些行。

-- 把 101 号客户的城市改成上海 UPDATE Customers SET City = '上海' WHERE CustomerID = 101;

二、多列更新

一条 UPDATE 改多列,逗号分隔:

UPDATE Customers SET City = '上海', FirstName = 'Alice2' WHERE CustomerID = 101;

三、基于原值更新

SET 可以用表达式,基于列原值算新值:

-- 所有 2024 年的订单金额加 10% UPDATE Orders SET Amount = Amount * 1.10 WHERE OrderDate BETWEEN '2024-01-01' AND '2024-12-31';

四、WHERE 是命根子

UPDATE 不加 WHERE 会更新全表所有行——这通常不是你想要的:

-- 危险!全表城市都改成上海 UPDATE Customers SET City = '上海';

图 5-2 UPDATE 安全流程

图 5-2 UPDATE 安全流程

五、安全习惯

  1. 先 SELECT 验证:用同样的 WHERE 写 SELECT,看影响哪些行、多少行。
  2. 确认再 UPDATE:行数符合预期再改写成 UPDATE。
  3. 事务包裹BEGIN; UPDATE...; 确认无误 COMMIT,有错 ROLLBACK
  4. 生产前备份:重要数据操作前备份。
-- 第 1 步:先看影响哪些 SELECT * FROM Customers WHERE CustomerID = 101; -- 第 2 步:确认后改写 UPDATE Customers SET City = '上海' WHERE CustomerID = 101;

六、UPDATE 的限制

UPDATE 不能改主键到已存在的值(主键约束),改外键也要满足参照完整性。批量 UPDATE 大表会锁表,注意性能影响。

⚠️ 常见坑:UPDATE 忘写 WHERE,全表更新——这是数据事故的头号原因。养成"先 SELECT 验证、再 UPDATE、事务包裹"的习惯,能避免绝大多数事故。

💡 关键直觉:UPDATE 的危险在 WHERE——漏写全表更新,写错范围误伤。先 SELECT 验证范围、事务包裹可回滚,是写 UPDATE 的安全底线。

核心回顾

  • 基本语法UPDATE 表 SET 列=值 WHERE 条件,SET 改值、WHERE 限定范围。
  • 多列更新:逗号分隔多个 列=值
  • 基于原值:SET 可用表达式,如 Amount = Amount * 1.1
  • WHERE 是命根子:不加 WHERE 全表更新,最危险。
  • 安全习惯:先 SELECT 验证 → 确认 → UPDATE(带 WHERE)→ 事务包裹可回滚 → 生产前备份。

下一节讲 DELETE——删数据,同样 WHERE 是命根子。

常见疑问

Q1:UPDATE 忘记 WHERE 的后果有多严重?

全表更新,且没有后悔药(除非有备份或事务)。线上库几百万行数据被一条 UPDATE 全改掉,是数据库事故排行榜第一名。应对:1) 养成先 SELECT 预览再 UPDATE 的习惯;2) 重要表操作前先备份;3) 关键操作包事务,确认后提交。

Q2:UPDATE 可以更新多个列吗?

可以,SET 列1=值1, 列2=值2,逗号分隔。注意 SET 里的计算是"同时基于旧值"还是"按顺序",标准 SQL 是同时基于旧值:SET a=b, b=a 交换两列值,两边都取旧值,能正确交换。

Q3:UPDATE 的值可以用子查询吗?

可以,SET 列 = (SELECT ...)。比如把每笔订单的金额更新为"客户消费总额的一定比例"。子查询要返回单值,否则报错。这类写法能实现跨表联动更新。

Q4:UPDATE 和事务的关系?

UPDATE 默认 autocommit 立即生效。多条更新想"要么全成功要么全回滚",用事务包裹:BEGIN 到 UPDATE... 到检查结果到 COMMIT / ROLLBACK。生产环境批量更新强烈建议走事务。

Q5:更新超大批量数据怎么控制影响?

分批次更新:按主键范围分批(WHERE id BETWEEN 1 AND 10000 循环推进),每批小、锁短、可观察进度。一次 UPDATE 全表几百万行会长时间锁表,阻塞在线业务。这也是数据变更上线的标准手法。

Q6:UPDATE 能改主键吗?

技术上可以,但强烈不建议:主键被外键引用时破坏参照完整性,且主键一变,历史记录关联全断。业务上"改主键"几乎总是设计错误的信号。

动手做一做

更新操作的危险程度与简单程度不成正比,建议用一个"安全实验"把它刻进记忆。

准备一张练习表,插入若干行数据,然后按下面的步骤做:

第一步,先写一条查询,用某个条件把要更新的行选出来,看看到底会影响哪些行。

第二步,确认无误后,把这条查询改写成更新语句,限定范围后执行。

第三步,为了体验不加条件的后果,先开一个事务,再执行一条不加条件的更新语句,查看影响了多少行——如果显示全表都被改了,立刻回滚。这一步请在测试库做,亲眼看看"漏写范围条件"的破坏力有多大。

第四步,练习一次同时更新多个列,观察值的组合方式。

第五步,试试用表达式基于原值计算新值,比如把金额统一增加比例,看更新后每行的变化。

这五步做完,你会牢牢记住:更新前先查询预览,更新时限定范围,关键操作放进事务。这三条习惯,是数据库从业者用无数次事故换来的经验,值得现在就养成。

一句话记忆

更新由两个部分构成:改哪些列、改哪些行。列由赋值语句决定,行由范围条件决定。范围条件是命根子,漏了它整表都会遭殃;先预览、再执行、套事务,是保命三连。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U