| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- -- =====================================================================
- -- 应急与指挥调度模块(dispatch)—— 人员字段补存「用户ID」迁移脚本
- -- 数据库:KingbaseES(PG 兼容模式),业务 schema = app_user
- --
- -- 背景(问题):
- -- 原设计只在业务表里存人员的「名称快照」(接报人 / 核验人 / 责任处置人 / 修订人 /
- -- 评估人 / 创建人 / 修改人),没有存 sys_user.user_id,导致:
- -- ① 用户改名后,历史数据无法再关联到本人;
- -- ② 无法按用户维度筛选(如「查我的接报」);
- -- ③ 与日志表的 oper_user_id 口径不一致(日志早就存了 id + 名称两份)。
- --
- -- 本脚本做什么:
- -- 1) 补 *_id 列(int8,与 sys_user.user_id 同类型):
- -- dis_event reporter_id / verifier_id / handler_id / create_user_id / update_user_id
- -- dis_plan create_user_id / update_user_id
- -- dis_plan_version editor_id
- -- dis_event_grade create_user_id / update_user_id
- -- dis_event_assess assessor_id / create_user_id / update_user_id
- -- dis_plan_library create_user_id
- -- dis_plan_match_record create_user_id
- -- 2) 按名称回填存量数据的 *_id —— **仅当该名称在 sys_user 中唯一命中时才回填**,
- -- 命中多条或查不到的一律留空,避免张冠李戴。
- --
- -- 口径说明(重要):
- -- · 名称列(reporter / verifier / handler / editor / assessor / create_by / update_by)
- -- **保留不删**,作为快照冗余:① 兼容存量数据;② 用户离职被删后仍能展示文字。
- -- 展示口径:以 *_id 反查 sys_user.nick_name 为准,查不到再退回名称快照。
- -- · create_by / update_by 是 RuoYi 通用字段,存的是**登录名 sys_user.user_name**,
- -- 故回填按 user_name 匹配;其余业务人员列存的是**昵称 sys_user.nick_name**,按 nick_name 匹配。
- -- · 不变更任何现存列的类型与取值,纯新增,不破坏既有功能。
- -- · dis_event_log / dis_plan_log 早在建模时就是 oper_user_id + oper_user_name 双字段,本脚本不涉及。
- --
- -- 幂等性:ADD COLUMN IF NOT EXISTS,可重复执行;回填只作用于 *_id IS NULL 的行。
- --
- -- ⚠️ KingbaseES 方言红线(本库实测):
- -- · `||` 在本实例被解析为**布尔 OR**,禁止用于字符串拼接,必须用 concat()。
- -- · information_schema.tables 会触发 sys_freespace() 权限校验,业务账号可能无权限,
- -- 判断表是否存在请用 to_regclass()。
- -- ⚠️ 客户端执行提示:
- -- · 语句失败后事务会挂起(25P02),后续查询一律报「当前事务被终止」,先执行 ROLLBACK; 再重试。
- -- · 选中运行时不要连带注释行,客户端会把注释并入语句并吃掉一个减号,导致语法错。
- -- · 本脚本为单事务,请整体执行(BEGIN; … COMMIT;),不要逐段选中执行。
- -- =====================================================================
- BEGIN;
- -- =====================================================================
- -- 一、补列
- -- =====================================================================
- -- 1.1 dis_event 事件主表
- ALTER TABLE app_user.dis_event ADD COLUMN IF NOT EXISTS reporter_id int8;
- ALTER TABLE app_user.dis_event ADD COLUMN IF NOT EXISTS verifier_id int8;
- ALTER TABLE app_user.dis_event ADD COLUMN IF NOT EXISTS handler_id int8;
- ALTER TABLE app_user.dis_event ADD COLUMN IF NOT EXISTS create_user_id int8;
- ALTER TABLE app_user.dis_event ADD COLUMN IF NOT EXISTS update_user_id int8;
- COMMENT ON COLUMN app_user.dis_event.reporter_id IS '接报人用户ID(sys_user.user_id);接报登记时固定取当前录入人员,与 reporter 快照同时写入';
- COMMENT ON COLUMN app_user.dis_event.verifier_id IS '核验人用户ID(sys_user.user_id);初判核实时的当前登录用户';
- COMMENT ON COLUMN app_user.dis_event.handler_id IS '责任处置人用户ID(sys_user.user_id);与 handler 快照、handler_phone 同时写入';
- COMMENT ON COLUMN app_user.dis_event.create_user_id IS '创建人用户ID(sys_user.user_id);create_by 存登录名,本列存ID';
- COMMENT ON COLUMN app_user.dis_event.update_user_id IS '最后修改人用户ID(sys_user.user_id);update_by 存登录名,本列存ID';
- -- 1.2 dis_plan 预案主表
- ALTER TABLE app_user.dis_plan ADD COLUMN IF NOT EXISTS create_user_id int8;
- ALTER TABLE app_user.dis_plan ADD COLUMN IF NOT EXISTS update_user_id int8;
- COMMENT ON COLUMN app_user.dis_plan.create_user_id IS '创建人用户ID(sys_user.user_id);create_by 存登录名,本列存ID';
- COMMENT ON COLUMN app_user.dis_plan.update_user_id IS '最后修改人用户ID(sys_user.user_id);update_by 存登录名,本列存ID';
- -- 1.3 dis_plan_version 预案版本快照表
- ALTER TABLE app_user.dis_plan_version ADD COLUMN IF NOT EXISTS editor_id int8;
- COMMENT ON COLUMN app_user.dis_plan_version.editor_id IS '修订人用户ID(sys_user.user_id);与 editor 名称快照同时写入';
- -- 1.4 dis_event_grade 事件分级标准表
- ALTER TABLE app_user.dis_event_grade ADD COLUMN IF NOT EXISTS create_user_id int8;
- ALTER TABLE app_user.dis_event_grade ADD COLUMN IF NOT EXISTS update_user_id int8;
- COMMENT ON COLUMN app_user.dis_event_grade.create_user_id IS '创建人用户ID(sys_user.user_id);create_by 存登录名,本列存ID';
- COMMENT ON COLUMN app_user.dis_event_grade.update_user_id IS '最后修改人用户ID(sys_user.user_id);update_by 存登录名,本列存ID';
- -- 1.5 dis_event_assess 事后评估表
- ALTER TABLE app_user.dis_event_assess ADD COLUMN IF NOT EXISTS assessor_id int8;
- ALTER TABLE app_user.dis_event_assess ADD COLUMN IF NOT EXISTS create_user_id int8;
- ALTER TABLE app_user.dis_event_assess ADD COLUMN IF NOT EXISTS update_user_id int8;
- COMMENT ON COLUMN app_user.dis_event_assess.assessor_id IS '评估人用户ID(sys_user.user_id);与 assessor 名称快照同时写入';
- COMMENT ON COLUMN app_user.dis_event_assess.create_user_id IS '创建人用户ID(sys_user.user_id);create_by 存登录名,本列存ID';
- COMMENT ON COLUMN app_user.dis_event_assess.update_user_id IS '最后修改人用户ID(sys_user.user_id);update_by 存登录名,本列存ID';
- -- 1.6 数字预案库 / 匹配记录(只有创建人,无人工操作列)
- ALTER TABLE app_user.dis_plan_library ADD COLUMN IF NOT EXISTS create_user_id int8;
- ALTER TABLE app_user.dis_plan_match_record ADD COLUMN IF NOT EXISTS create_user_id int8;
- COMMENT ON COLUMN app_user.dis_plan_library.create_user_id IS '创建人用户ID(sys_user.user_id);create_by 存登录名,本列存ID';
- COMMENT ON COLUMN app_user.dis_plan_match_record.create_user_id IS '创建人用户ID(sys_user.user_id);create_by 存登录名,本列存ID';
- -- 1.7 索引:列表可能按「我的接报 / 我核实的」筛选
- CREATE INDEX IF NOT EXISTS idx_dis_event_reporter_id ON app_user.dis_event(reporter_id);
- CREATE INDEX IF NOT EXISTS idx_dis_event_verifier_id ON app_user.dis_event(verifier_id);
- CREATE INDEX IF NOT EXISTS idx_dis_event_handler_id ON app_user.dis_event(handler_id);
- -- =====================================================================
- -- 二、存量数据回填
- -- 匹配口径:昵称列 → sys_user.nick_name;create_by/update_by → sys_user.user_name。
- -- 只回填「唯一命中」的名称;同名(如两个「张伟」)或查不到的一律留空。
- -- =====================================================================
- -- 2.1 dis_event —— 接报人(昵称)
- UPDATE app_user.dis_event e
- SET reporter_id = m.user_id
- FROM (SELECT nick_name, min(user_id) AS user_id, count(*) AS cnt
- FROM app_user.sys_user WHERE del_flag = '0' GROUP BY nick_name) m
- WHERE e.reporter_id IS NULL
- AND e.reporter IS NOT NULL
- AND e.reporter = m.nick_name
- AND m.cnt = 1;
- -- 2.2 dis_event —— 核验人(昵称)
- UPDATE app_user.dis_event e
- SET verifier_id = m.user_id
- FROM (SELECT nick_name, min(user_id) AS user_id, count(*) AS cnt
- FROM app_user.sys_user WHERE del_flag = '0' GROUP BY nick_name) m
- WHERE e.verifier_id IS NULL
- AND e.verifier IS NOT NULL
- AND e.verifier = m.nick_name
- AND m.cnt = 1;
- -- 2.3 dis_event —— 责任处置人(昵称)
- UPDATE app_user.dis_event e
- SET handler_id = m.user_id
- FROM (SELECT nick_name, min(user_id) AS user_id, count(*) AS cnt
- FROM app_user.sys_user WHERE del_flag = '0' GROUP BY nick_name) m
- WHERE e.handler_id IS NULL
- AND e.handler IS NOT NULL
- AND e.handler = m.nick_name
- AND m.cnt = 1;
- -- 2.4 dis_event —— 创建人 / 修改人(登录名)
- UPDATE app_user.dis_event e
- SET create_user_id = m.user_id
- FROM (SELECT user_name, min(user_id) AS user_id, count(*) AS cnt
- FROM app_user.sys_user WHERE del_flag = '0' GROUP BY user_name) m
- WHERE e.create_user_id IS NULL
- AND e.create_by IS NOT NULL
- AND e.create_by = m.user_name
- AND m.cnt = 1;
- UPDATE app_user.dis_event e
- SET update_user_id = m.user_id
- FROM (SELECT user_name, min(user_id) AS user_id, count(*) AS cnt
- FROM app_user.sys_user WHERE del_flag = '0' GROUP BY user_name) m
- WHERE e.update_user_id IS NULL
- AND e.update_by IS NOT NULL
- AND e.update_by = m.user_name
- AND m.cnt = 1;
- -- 2.5 dis_plan —— 创建人 / 修改人(登录名)
- UPDATE app_user.dis_plan p
- SET create_user_id = m.user_id
- FROM (SELECT user_name, min(user_id) AS user_id, count(*) AS cnt
- FROM app_user.sys_user WHERE del_flag = '0' GROUP BY user_name) m
- WHERE p.create_user_id IS NULL
- AND p.create_by IS NOT NULL
- AND p.create_by = m.user_name
- AND m.cnt = 1;
- UPDATE app_user.dis_plan p
- SET update_user_id = m.user_id
- FROM (SELECT user_name, min(user_id) AS user_id, count(*) AS cnt
- FROM app_user.sys_user WHERE del_flag = '0' GROUP BY user_name) m
- WHERE p.update_user_id IS NULL
- AND p.update_by IS NOT NULL
- AND p.update_by = m.user_name
- AND m.cnt = 1;
- -- 2.6 dis_plan_version —— 修订人(昵称)
- UPDATE app_user.dis_plan_version v
- SET editor_id = m.user_id
- FROM (SELECT nick_name, min(user_id) AS user_id, count(*) AS cnt
- FROM app_user.sys_user WHERE del_flag = '0' GROUP BY nick_name) m
- WHERE v.editor_id IS NULL
- AND v.editor IS NOT NULL
- AND v.editor = m.nick_name
- AND m.cnt = 1;
- -- 2.7 dis_event_grade —— 创建人 / 修改人(登录名)
- UPDATE app_user.dis_event_grade g
- SET create_user_id = m.user_id
- FROM (SELECT user_name, min(user_id) AS user_id, count(*) AS cnt
- FROM app_user.sys_user WHERE del_flag = '0' GROUP BY user_name) m
- WHERE g.create_user_id IS NULL
- AND g.create_by IS NOT NULL
- AND g.create_by = m.user_name
- AND m.cnt = 1;
- UPDATE app_user.dis_event_grade g
- SET update_user_id = m.user_id
- FROM (SELECT user_name, min(user_id) AS user_id, count(*) AS cnt
- FROM app_user.sys_user WHERE del_flag = '0' GROUP BY user_name) m
- WHERE g.update_user_id IS NULL
- AND g.update_by IS NOT NULL
- AND g.update_by = m.user_name
- AND m.cnt = 1;
- -- 2.8 dis_event_assess —— 评估人(昵称)
- UPDATE app_user.dis_event_assess a
- SET assessor_id = m.user_id
- FROM (SELECT nick_name, min(user_id) AS user_id, count(*) AS cnt
- FROM app_user.sys_user WHERE del_flag = '0' GROUP BY nick_name) m
- WHERE a.assessor_id IS NULL
- AND a.assessor IS NOT NULL
- AND a.assessor = m.nick_name
- AND m.cnt = 1;
- -- 2.9 dis_event_assess —— 创建人 / 修改人(登录名)
- UPDATE app_user.dis_event_assess a
- SET create_user_id = m.user_id
- FROM (SELECT user_name, min(user_id) AS user_id, count(*) AS cnt
- FROM app_user.sys_user WHERE del_flag = '0' GROUP BY user_name) m
- WHERE a.create_user_id IS NULL
- AND a.create_by IS NOT NULL
- AND a.create_by = m.user_name
- AND m.cnt = 1;
- UPDATE app_user.dis_event_assess a
- SET update_user_id = m.user_id
- FROM (SELECT user_name, min(user_id) AS user_id, count(*) AS cnt
- FROM app_user.sys_user WHERE del_flag = '0' GROUP BY user_name) m
- WHERE a.update_user_id IS NULL
- AND a.update_by IS NOT NULL
- AND a.update_by = m.user_name
- AND m.cnt = 1;
- -- 2.10 dis_plan_library / dis_plan_match_record —— 创建人(登录名)
- UPDATE app_user.dis_plan_library l
- SET create_user_id = m.user_id
- FROM (SELECT user_name, min(user_id) AS user_id, count(*) AS cnt
- FROM app_user.sys_user WHERE del_flag = '0' GROUP BY user_name) m
- WHERE l.create_user_id IS NULL
- AND l.create_by IS NOT NULL
- AND l.create_by = m.user_name
- AND m.cnt = 1;
- UPDATE app_user.dis_plan_match_record r
- SET create_user_id = m.user_id
- FROM (SELECT user_name, min(user_id) AS user_id, count(*) AS cnt
- FROM app_user.sys_user WHERE del_flag = '0' GROUP BY user_name) m
- WHERE r.create_user_id IS NULL
- AND r.create_by IS NOT NULL
- AND r.create_by = m.user_name
- AND m.cnt = 1;
- COMMIT;
- -- =====================================================================
- -- 三、执行后自检(另开查询窗口执行,不属于本事务)
- -- =====================================================================
- -- 1) 列是否补齐
- -- SELECT table_name, column_name FROM information_schema.columns
- -- WHERE table_schema = 'app_user' AND column_name LIKE '%_id'
- -- AND table_name IN ('dis_event','dis_plan','dis_plan_version','dis_event_grade',
- -- 'dis_event_assess','dis_plan_library','dis_plan_match_record')
- -- ORDER BY table_name, column_name;
- -- 2) 回填覆盖率(total = 有名称的行数,filled = 已回填用户ID的行数)
- -- SELECT 'dis_event.reporter' AS col, count(reporter) AS total, count(reporter_id) AS filled FROM app_user.dis_event
- -- UNION ALL SELECT 'dis_event.verifier', count(verifier), count(verifier_id) FROM app_user.dis_event
- -- UNION ALL SELECT 'dis_event.handler', count(handler), count(handler_id) FROM app_user.dis_event
- -- UNION ALL SELECT 'dis_event.create_by', count(create_by), count(create_user_id) FROM app_user.dis_event
- -- UNION ALL SELECT 'dis_plan.create_by', count(create_by), count(create_user_id) FROM app_user.dis_plan
- -- UNION ALL SELECT 'dis_plan_version.editor', count(editor), count(editor_id) FROM app_user.dis_plan_version;
- -- 3) 名称与ID是否对得上(应返回 0 行)
- -- SELECT id, reporter, reporter_id FROM app_user.dis_event e
- -- WHERE reporter_id IS NOT NULL
- -- AND NOT EXISTS (SELECT 1 FROM app_user.sys_user u WHERE u.user_id = e.reporter_id AND u.nick_name = e.reporter);
|