如何在PostgreSQL中使用变量返回多个查询结果?
在PostgreSQL中实现MSSQL变量式多查询的等效方案
针对你从MSSQL转PostgreSQL时遇到的变量复用、多查询返回结果的问题,以下是几种可行的解决方案:
为什么之前的尝试失败
- CTE方案:PostgreSQL的CTE仅对单个查询块生效,多个独立的
SELECT语句无法共享同一个CTE,所以第二个查询会找不到vars。 - DO块方案:PL/pgSQL的
DO块是匿名执行块,不能直接返回查询结果——它只能执行逻辑,若要丢弃结果用PERFORM,但要返回结果必须用函数封装。
方案1:使用临时表存储变量值
临时表在当前数据库会话内有效,所有后续查询都能访问,是最接近MSSQL变量复用逻辑的方案:
-- 把目标id存入临时表(UniqueName唯一,所以只会有一条记录) CREATE TEMP TABLE var_id AS SELECT Id FROM SomeTable WHERE UniqueName = 'foo'; -- 执行多个查询,复用临时表中的id SELECT * FROM SomeTable WHERE Id = (SELECT Id FROM var_id); SELECT * FROM AnotherTable WHERE Id = (SELECT Id FROM var_id); SELECT * FROM FinalTable WHERE Id = (SELECT Id FROM var_id); -- 临时表会在会话结束后自动删除,也可以手动清理 -- DROP TABLE var_id;
方案2:封装为PL/pgSQL函数返回多结果集
如果需要把逻辑封装起来,可创建一个返回多个结果集的函数(PostgreSQL 11+支持):
CREATE OR REPLACE FUNCTION get_related_data() RETURNS SETOF record AS $$ DECLARE v_id integer; -- PostgreSQL变量不需要@前缀 BEGIN -- 赋值变量 SELECT Id INTO v_id FROM SomeTable WHERE UniqueName = 'foo'; -- 依次返回三个结果集 RETURN QUERY SELECT * FROM SomeTable WHERE Id = v_id; RETURN QUERY SELECT * FROM AnotherTable WHERE Id = v_id; RETURN QUERY SELECT * FROM FinalTable WHERE Id = v_id; END; $$ LANGUAGE plpgsql;
调用时需要指定每个结果集的结构(匹配对应表的字段):
-- 获取第一个表的结果 SELECT * FROM get_related_data() AS some_table(Id integer, UniqueName text, /* 其他字段 */); -- 获取第二个表的结果 SELECT * FROM get_related_data() AS another_table(Id integer, /* 其他字段 */); -- 获取第三个表的结果 SELECT * FROM get_related_data() AS final_table(Id integer, /* 其他字段 */);
方案3:psql交互模式下用\gset赋值变量
如果是在psql命令行手动操作,可以用\gset将查询结果赋值给变量:
-- 查询id并赋值给v_id变量 SELECT Id AS v_id FROM SomeTable WHERE UniqueName = 'foo' \gset -- 直接使用变量执行查询 SELECT * FROM SomeTable WHERE Id = :v_id; SELECT * FROM AnotherTable WHERE Id = :v_id; SELECT * FROM FinalTable WHERE Id = :v_id;
内容的提问来源于stack exchange,提问作者Learning AWS and PostgreSQL
相关产品推荐
相关产品推荐

