从Postgres返回多个结果集:refresor,函数还是新功能?

时间:2018-11-22 19:33:01

标签: sql postgresql

前提:

一个实体有许多子孙(在此情况下分别为要旨,版本和文件)。当需要它(要旨)时,我们也需要它的子代(版本)和孙子代(版本文件)。在这里,我实际上是在努力尽可能多地使用SQL,而不是将多个查询组合在一起并用脚本语言将它们组合在一起。能做到吗支持将查询发送到PostgresQL数据库的工具是否支持返回的结果?

现有技术:

架构:

Schema (and SQL to insert mock data)

我通过存储函数的尝试(注意,我已简化为仅父/子返回集,暂时跳过了孙子):

CREATE OR REPLACE FUNCTION get_gist_with_children(gist_ref refcursor, 

version_ref refcursor, gist_id_in UUID)
RETURNS SETOF refcursor AS $$
BEGIN
 OPEN gist_ref FOR SELECT * from gist where gist_id = gist_id_in;
 RETURN NEXT gist_ref;

 OPEN version_ref FOR SELECT * from version where gist_id = gist_id_in;
 RETURN NEXT version_ref;
END;
$$ LANGUAGE plpgsql;

用于访问该功能的查询:

BEGIN;

SELECT get_gist_with_children('gist_ref', 'version_ref', <replace with known UUID of gist record>);

FETCH ALL IN "gist_ref";
FETCH ALL IN "version_ref";
COMMIT;

返回POSTICO Postico是PostgresQL GUI,仅返回两行中的refcursor符号字符串。 screenshot of Postico results

返回psql psql返回第一组结果,然后...挂起? screenshot of psql hanging

注意:我可以成功查询该gist_id上的两个表以及在单独查询中返回的记录。

Postgres是否有新功能可以实现此目标?有没有更好的方法使用游标呢?工具(psql,Postico)不能处理多个数据集的返回是真正的问题吗?对前进的方式感到好奇,而不仅仅是通过脚本语言退缩。

2 个答案:

答案 0 :(得分:0)

PostgreSQL数据库引擎完全能够处理每个连接(甚至每个调用)多个打开的结果集。它可以保留使用多个“结果集”从单个调用返回的多个游标。

不要害怕使用它们。只需在过程中尝试多个SELECT并执行一次调用即可。然后,很容易验证您是否可以从所有结果集中读取数据,甚至可以并行读取。

如果您在MySQL上问了同样的问题,那么答案肯定是“否”。 MySQL的局限性更大。但是使用PostgreSQL,这是完全可能的。

答案 1 :(得分:0)

CREATE OR REPLACE FUNCTION public.TestReturnMultipleTales
( 
 param_coid integer, 
 ref1 refcursor,
 ref2 refcursor
)
RETURNS SETOF refcursor 
LANGUAGE 'plpgsql'
COST 100
VOLATILE PARALLEL UNSAFE
ROWS 1000

AS $BODY$
DECLARE
            
BEGIN
  OPEN ref1 FOR SELECT * FROM dbo.tbl1 WHERE coid = param_coid;
  RETURN NEXT ref1;

  OPEN ref2 FOR SELECT * FROM dbo.tbl2 LIMIT 5;
  RETURN NEXT ref2;
END;
$BODY$;

BEGIN;
    SELECT football_players.show_cities_multiple(123456, 'Ref1', 'Ref2');
    FETCH ALL IN "Ref1";
    FETCH ALL IN "Ref2";
COMMIT;