PostgreSQL pg_get_serial_sequence传schema及多setval语句报错问题
PostgreSQL 序列重置脚本报错修复
两个报错的根因
- 第一个「美元引号未终止」报错:是因为动态SQL拼接时单引号转义逻辑混乱,同时你把
alerts.nds_email_message直接写在字符串拼接里,没有加引号作为字符串字面量,被解析成了不存在的变量,最终导致块结构解析失败。另外pg_get_serial_sequence本身就支持传入带schema前缀的完整表名,不需要特殊处理schema参数。 - 第二个「查询无结果数据存储目标」报错:是PL/pgSQL的语法限制,在
BEGIN...END块中,普通SELECT语句必须指定结果存储的变量,如果不需要接收返回结果,需要用PERFORM关键字替换SELECT。
可直接运行的正确代码
下面的代码可以在同一个PL/pgSQL块内完成alerts schema下多张表的序列重置,不需要动态SQL拼接,不会出现转义错误:
DO $$ BEGIN -- 重置incident_log表主键序列 PERFORM setval( pg_get_serial_sequence('alerts.incident_log', 'incident_log_id'), COALESCE(max(incident_log_id), 0) + 1, false ) FROM alerts.incident_log; -- 重置nds_email_message表主键序列 PERFORM setval( pg_get_serial_sequence('alerts.nds_email_message', 'nds_email_message_id'), COALESCE(max(nds_email_message_id), 0) + 1, false ) FROM alerts.nds_email_message; -- 重置nds_fax_message表主键序列 PERFORM setval( pg_get_serial_sequence('alerts.nds_fax_message', 'nds_fax_message_id'), COALESCE(max(nds_fax_message_id), 0) + 1, false ) FROM alerts.nds_fax_message; END $$;
补充说明
- 如果后续需要新增其他表的序列重置,直接参照上面的格式新增
PERFORM语句块即可,表名固定的场景不需要使用EXECUTE执行动态SQL,能避免绝大多数转义问题。 pg_get_serial_sequence的第一个参数传入格式为'schema名.表名'的字符串即可,不需要拆分schema单独传参。
内容的提问来源于stack exchange,提问作者Jagdish
相关产品推荐
相关产品推荐

