| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- -- =====================================================================
- -- dispatch_fix_all_identity.sql
- -- 一次性对齐 app_user 下所有 dis_* 表的主键自增序列
- -- ---------------------------------------------------------------------
- -- 背景:调度模块各表(dis_event / dis_event_log / dis_plan / dis_plan_version /
- -- dis_event_grade / dis_event_assess / dis_plan_log / dis_plan_library /
- -- dis_plan_match_record 等)由 MySQL 迁移至 Kingbase,迁移数据时带显式 id
- -- 插入,GENERATED BY DEFAULT AS IDENTITY 的序列不会自动推进;此后不带
- -- id 的 INSERT 会从序列起点发号(如发 0),撞已存在行,报主键冲突。
- -- 修复:遍历 app_user 下所有 dis_% 表,把 id 列关联的序列 setval 到 max(id)
- -- (setval(seq, max, true) → 下一个发号 = max+1)。幂等可重复执行。
- -- 执行方式:KingbaseES 客户端。逐段执行;某段失败先 ROLLBACK 再继续下一段。
- -- =====================================================================
- -- ---------------------------------------------------------------------
- -- 步骤 0(可选):先看各表现状——max(id) 与序列名,便于核对
- -- ---------------------------------------------------------------------
- SELECT c.relname AS 表名,
- (SELECT COALESCE(max(id), 0) FROM app_user.dis_event) AS 说明_另查,
- d.objid::regclass::text AS 关联序列
- FROM pg_class c
- JOIN pg_namespace n ON n.oid = c.relnamespace
- LEFT JOIN pg_depend d
- ON d.refobjid = c.oid
- AND d.classid = 'pg_class'::regclass
- AND d.deptype IN ('a', 'i')
- LEFT JOIN pg_attribute a
- ON a.attrelid = d.refobjid AND a.attnum = d.refobjsubid AND a.attname = 'id'
- WHERE n.nspname = 'app_user'
- AND c.relname LIKE 'dis_%'
- AND c.relkind = 'r';
- -- ---------------------------------------------------------------------
- -- 步骤 1(首选):自动遍历所有 dis_% 表,校准 id 序列
- -- 执行成功会逐表 NOTICE 输出「表名 -> 序列名 (next=...)」
- -- ---------------------------------------------------------------------
- DO $$
- DECLARE
- t record;
- seqname text;
- maxid bigint;
- BEGIN
- FOR t IN
- SELECT c.relname AS table_name
- FROM pg_class c
- JOIN pg_namespace n ON n.oid = c.relnamespace
- WHERE n.nspname = 'app_user'
- AND c.relname LIKE 'dis\_%' ESCAPE '\'
- AND c.relkind = 'r'
- LOOP
- EXECUTE format('SELECT COALESCE(max(id), 0) FROM app_user.%I', t.table_name) INTO maxid;
- -- 找 id 列关联的序列(serial=deptype a / identity=deptype i)
- SELECT d.objid::regclass::text INTO seqname
- FROM pg_depend d
- JOIN pg_attribute a ON a.attrelid = d.refobjid AND a.attnum = d.refobjsubid
- JOIN pg_class sc ON sc.oid = d.objid AND sc.relkind = 'S'
- JOIN pg_namespace sn ON sn.oid = sc.relnamespace AND sn.nspname = 'app_user'
- WHERE d.refobjid = format('app_user.%I', t.table_name)::regclass
- AND a.attname = 'id'
- AND d.classid = 'pg_class'::regclass
- AND d.deptype IN ('a', 'i')
- LIMIT 1;
- IF seqname IS NOT NULL THEN
- EXECUTE format('SELECT setval(%L::regclass, %s, true)', seqname, GREATEST(maxid, 1));
- RAISE NOTICE '% -> % (next=%)', t.table_name, seqname, maxid + 1;
- ELSE
- RAISE NOTICE '% -> 未找到关联序列,请用步骤 2 手工处理', t.table_name;
- END IF;
- END LOOP;
- END $$;
- -- ---------------------------------------------------------------------
- -- 步骤 2(保底):步骤 1 中提示「未找到关联序列」的表,手工对齐
- -- 先查该表 max(id),把下面的 <n> 替换为 max(id)(RESTART WITH 生效值即下一个发号):
- -- ALTER TABLE app_user.表名 ALTER COLUMN id RESTART WITH <max(id)>;
- --
- -- 例(编号仅为示例,以步骤 0 查到的 max(id) 为准):
- -- ALTER TABLE app_user.dis_event ALTER COLUMN id RESTART WITH 100;
- -- ALTER TABLE app_user.dis_event_log ALTER COLUMN id RESTART WITH 300;
- -- ALTER TABLE app_user.dis_event_assess ALTER COLUMN id RESTART WITH 10;
- -- ---------------------------------------------------------------------
- -- ---------------------------------------------------------------------
- -- 步骤 3:核验——逐表 nextval 应等于 max(id) + 1(多表循环核验可重复步骤 0)
- -- 示例:
- -- SELECT COALESCE(max(id), 0) AS max_id,
- -- nextval(pg_get_serial_sequence('app_user.dis_event', 'id')) AS next_id
- -- FROM app_user.dis_event;
- -- 注意:如 pg_get_serial_sequence 在 KES 上返回空,则改用步骤 0 查到的序列名:
- -- SELECT nextval('app_user.dis_event_id_seq');
- -- ---------------------------------------------------------------------
|