-- 2026-10-16-02-brands-renumber-repair.sql -- -- 修复 2026-10-16-01 初版留下的半途状态:初版第 ② 步的 JOIN 条件写错(拿子查询里的 -id -- 去比 b.id),一行都没匹配上,于是只完成了「整批挪到负区间」,紧接着第 ③ 步按当时的最大正值 -- (19)设了序列。结果:23218 个品牌的 id 变成负数、序列指向 20。 -- -- 本迁移把负数行按原 id 升序落回 20.. 的连续区间,并重新对齐序列。 -- 若 01 已正确完成(不存在负数行),本迁移直接跳过 —— 因此对全新建库也是无副作用的。 -- -- 安全性同上:没有任何行引用这批 id(brand_runways.brand_id 最大 7)。19 个种子不动。 DO $$ DECLARE v_moved integer; v_after integer; BEGIN IF NOT EXISTS (SELECT 1 FROM brands WHERE id < 0) THEN RAISE NOTICE '[brands-renumber-repair] 不存在负数行,无需修复,跳过'; RETURN; END IF; -- 目标区间若已被占用,继续重排会撞主键:宁可中止也不要写出坏数据。 IF EXISTS (SELECT 1 FROM brands WHERE id BETWEEN 20 AND 3096) THEN RAISE EXCEPTION '[brands-renumber-repair] 20..3096 已被占用,重排会撞主键,已中止'; END IF; UPDATE brands b SET id = m.new_id FROM ( SELECT id AS neg_id, (row_number() OVER (ORDER BY -id))::integer + 19 AS new_id FROM brands WHERE id < 0 ) m WHERE b.id = m.neg_id; GET DIAGNOSTICS v_moved = ROW_COUNT; SELECT max(id) INTO v_after FROM brands; PERFORM setval(pg_get_serial_sequence('brands', 'id'), v_after); RAISE NOTICE '[brands-renumber-repair] 完成:% 行落回连续区间,id 最大值 %,序列下次给出 %', v_moved, v_after, v_after + 1; END $$;