百科

sql批量修改数据

时间:2010-12-5 17:23:32  作者:综合   来源:探索  查看:  评论:0
内容摘要: 上周我接手了一个烂摊子:客户数据库里三千多条产品记录,分类字段全部错位。原因很狗血——前任开发在导入数据时,把Excel里的一列复制错了。人工改?那得改到下周。我直接写了条SQL,UPDATE pr

上周我接手了一个烂摊子:客户数据库里三千多条产品记录,量修分类字段全部错位。改数原因很狗血——前任开发在导入数据时,量修把Excel里的改数一列复制错了。人工改?量修那得改到下周。我直接写了条SQL,改数UPDATE products SET category = 'A' WHERE category = '旧值',量修三秒跑完。改数这就是量修SQL批量修改的日常:一条语句,解决几千行数据的改数迁移或纠错。

但别急着高兴。量修批量修改最怕的改数不是写不出SQL,而是量修你没想清楚“改哪些行”。我见过太多人直接跑UPDATE 表 SET 字段 = 新值,改数连WHERE都不带——好家伙,量修全表覆盖,连备份都没做。上个月有个同行就这么干,把用户余额全部清零,最后只能从binlog里捞数据,折腾了一整夜。所以我的铁律是:先SELECT COUNT(*)看看要影响多少行,再决定要不要动手。

真正实用的批量修改,往往得靠条件组合拳。比如你要把“已离职员工”的状态改成“禁用”,同时把他们的部门字段清空。一条语句搞定:
UPDATE employees SET status = 'disabled', department = NULL WHERE resignation_date IS NOT NULL
这里的关键是那个WHERE——别用!=或NOT IN,除非你百分百确定排除项。用IS NULL反而更安全,因为SQL里的NULL比较是个坑,= NULL永远不成立,你得写IS NULL。

再复杂点的场景,比如按另一张表的数据来更新。这时候就别用子查询硬套了,直接上JOIN。举个例子:
UPDATE orders o INNER JOIN customers c ON o.customer_id = c.id SET o.discount = c.level * 0.1
这种写法比逐条UPDATE快一个数量级,而且逻辑清晰。我习惯在改之前先跑一遍同样的SELECT验证结果,比如SELECT o.id, o.discount FROM orders o INNER JOIN customers c ...,看到输出没问题再换成UPDATE。别嫌麻烦,这能救你命。

还有个容易翻车的地方——字符串里的引号。比如你要把所有产品描述里的“红色”改成“深红”,但描述里可能有单引号。直接写SET description = REPLACE(description, '红色', '深红')没问题,可要是替换内容本身带引号,比如要把“it's”改成“it is”,你得转义:REPLACE(description, 'it''s', 'it is')——两个单引号代表一个。这种事没经验的人根本想不到,第一次跑报错时别慌,多半是引号问题。

最后说个实战技巧:分批执行。如果表特别大,比如几百万行,一次性UPDATE会锁表很久,可能把线上业务卡死。我一般用WHERE id BETWEEN 1 AND 10000这样循环跑,或者用LIMIT配合主键范围。写个存储过程或者脚本,每批跑完sleep几秒。虽然代码啰嗦点,但稳。上周我改一个五百万行的日志表,就是按天分批,每批十万行,跑了五十分钟,期间业务完全没感知。

批量修改这事,说白了就是“想清楚再动手,动手前先备份”。备份不是让你拷贝整个库,至少把要改的表CREATE TABLE 表名_bak AS SELECT * FROM 表名一下。我吃过亏,所以现在养成习惯:改之前备份,改之后立刻验证SELECT几条关键记录,确认无误再通知别人。别嫌啰嗦,SQL这东西,跑错了可没后悔药。

最近更新
热门排行
copyright © 2026 powered by 力不从心网   sitemap