pgAdmin 4v2.1记录数显示异常求助:实际与显示受影响数不符
问题分析与解决方案
你碰到的这个情况我之前在老版本pgAdmin上也见过类似的,结合你的使用场景(用row_number()生成主键插入脚本后出现异常),大概率是脚本逻辑、旧版本pgAdmin的bug,或者数据库触发器/规则导致的,下面给你拆解排查方向:
1. 先确认:数据库实际数据是否真的在重复插入?
先别着急盯着pgAdmin的提示,先查实际数据——执行这个语句看看目标表的行数:
SELECT COUNT(*) FROM your_target_table;
如果每次执行插入脚本后,行数确实增加了n条,那问题出在你的插入逻辑上;如果行数没变化,只是pgAdmin显示异常,那就是pgAdmin 4 v2.1的老版本bug,直接升级就能解决。
2. 排查插入脚本的逻辑漏洞
你用row_number()生成主键的脚本,有没有做重复插入的过滤?比如如果脚本是类似下面这种:
INSERT INTO target_table (id, col1, col2) SELECT row_number() OVER (ORDER BY s.id) + (SELECT MAX(id) FROM target_table), s.col1, s.col2 FROM source_table s;
这种写法每次执行都会把source_table的所有行再插入一遍,因为MAX(id)会随着每次插入变大,自然每次受影响行数都是n(source_table的行数),叠加起来就会显示n*x条。
解决办法是给插入脚本加过滤条件,比如只插入目标表中不存在的行:
INSERT INTO target_table (id, col1, col2) SELECT row_number() OVER (ORDER BY s.id) + (SELECT COALESCE(MAX(id), 0) FROM target_table), s.col1, s.col2 FROM source_table s WHERE s.id NOT IN (SELECT source_id FROM target_table); -- 这里根据实际关联字段调整
3. 检查目标表是否有触发器/规则导致多插入
如果目标表上存在INSERT触发器或者规则(Rule),可能会让一次INSERT操作触发多次实际插入。比如触发器里又执行了其他INSERT,或者规则定义了INSERT时的额外复制行为,这会让pgAdmin统计的受影响行数变成实际插入的总次数。
用下面的语句检查:
-- 查看目标表的触发器 SELECT tgname FROM pg_trigger WHERE tgrelid = 'target_table'::regclass; -- 查看目标表的INSERT规则 SELECT rulename FROM pg_rewrite WHERE ev_class = 'target_table'::regclass AND ev_type = 'INSERT';
如果有这类对象,检查它们的逻辑是否会生成额外的插入操作。
4. 老版本pgAdmin的UI统计bug
pgAdmin 4 v2.1是2018年的老版本了,当时的UI和查询统计模块有不少bug,比如重复统计受影响行数、结果集显示异常等。如果前面排查后实际数据是正常的,那就是pgAdmin的显示问题,直接升级到最新稳定版(比如v7.x)就能解决——新版本不仅修复了这些bug,功能也完善很多。
内容的提问来源于stack exchange,提问作者ps2goat

