本节摘要:UPDATE 修改现有行的列值。本节讲 SET 改值、WHERE 限定范围、多列更新,以及"忘写 WHERE 全表更新"这个最危险的坑。
阅读完本节,你应当能够:
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';
UPDATE 不加 WHERE 会更新全表所有行——这通常不是你想要的:
-- 危险!全表城市都改成上海 UPDATE Customers SET City = '上海';

BEGIN; UPDATE...; 确认无误 COMMIT,有错 ROLLBACK。-- 第 1 步:先看影响哪些 SELECT * FROM Customers WHERE CustomerID = 101; -- 第 2 步:确认后改写 UPDATE Customers SET City = '上海' WHERE CustomerID = 101;
UPDATE 不能改主键到已存在的值(主键约束),改外键也要满足参照完整性。批量 UPDATE 大表会锁表,注意性能影响。
⚠️ 常见坑:UPDATE 忘写 WHERE,全表更新——这是数据事故的头号原因。养成"先 SELECT 验证、再 UPDATE、事务包裹"的习惯,能避免绝大多数事故。
💡 关键直觉:UPDATE 的危险在 WHERE——漏写全表更新,写错范围误伤。先 SELECT 验证范围、事务包裹可回滚,是写 UPDATE 的安全底线。
UPDATE 表 SET 列=值 WHERE 条件,SET 改值、WHERE 限定范围。列=值。Amount = Amount * 1.1。下一节讲 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 能改主键吗?
技术上可以,但强烈不建议:主键被外键引用时破坏参照完整性,且主键一变,历史记录关联全断。业务上"改主键"几乎总是设计错误的信号。
更新操作的危险程度与简单程度不成正比,建议用一个"安全实验"把它刻进记忆。
准备一张练习表,插入若干行数据,然后按下面的步骤做:
第一步,先写一条查询,用某个条件把要更新的行选出来,看看到底会影响哪些行。
第二步,确认无误后,把这条查询改写成更新语句,限定范围后执行。
第三步,为了体验不加条件的后果,先开一个事务,再执行一条不加条件的更新语句,查看影响了多少行——如果显示全表都被改了,立刻回滚。这一步请在测试库做,亲眼看看"漏写范围条件"的破坏力有多大。
第四步,练习一次同时更新多个列,观察值的组合方式。
第五步,试试用表达式基于原值计算新值,比如把金额统一增加比例,看更新后每行的变化。
这五步做完,你会牢牢记住:更新前先查询预览,更新时限定范围,关键操作放进事务。这三条习惯,是数据库从业者用无数次事故换来的经验,值得现在就养成。
更新由两个部分构成:改哪些列、改哪些行。列由赋值语句决定,行由范围条件决定。范围条件是命根子,漏了它整表都会遭殃;先预览、再执行、套事务,是保命三连。