首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Postgres函数:返回多个表

问Postgres函数:返回多个表
EN

Stack Overflow用户
提问于 2016-04-19 19:31:57
回答 5查看 13.1K关注 0票数 6

postgres函数可以返回几个不同类型的结果集吗?

类似于:

代码语言:javascript
复制
CREATE OR REPLACE FUNCTION getUserById()
RETURNS setof ???
AS
$$
BEGIN

return query select id, name /* and other columns */ from users where id = 1;
return query select id, phone_number from user_phones where user_id = 1

END
$$
LANGUAGE plpgsql;

我不想使用连接,因为用户的几个电话是可能的。此外,避免使用游标也是很好的。这在MS SQL中是可能的,我想在postgres中做同样的事情。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-04-22 20:17:52

在寻找之后,找不到任何更好的解决方案,因为使用游标。

代码语言:javascript
复制
CREATE FUNCTION load_page(_session INT) RETURNS setof refcursor AS
$$
DECLARE c_top_items refcursor;
DECLARE c_shopping_cart refcursor;
BEGIN
    OPEN c_top_items FOR
        SELECT t.name, t.description
        FROM top_item t
        ORDER BY t.popularity DESC
        LIMIT 10;
    RETURN NEXT c_top_items;
    OPEN c_shopping_cart FOR
        SELECT c.product_id, c.product_name, c.quantity
        FROM shopping_cart c
        WHERE c.session_id = _session
        ORDER BY c.id;
    RETURN NEXT c_shopping_cart;
END;
$$ LANGUAGE plpgsql;

和呼叫:

代码语言:javascript
复制
BEGIN;
SELECT load_page(mySession);
FETCH ALL IN "<server cursor 1>";
FETCH ALL IN "<server cursor 2>";
COMMIT;
票数 5
EN

Stack Overflow用户

发布于 2017-01-17 05:49:48

我不想使用joins,因为用户可以使用多个电话。

这不是在PostgreSQL中避免使用JOIN%s的理由。完全没有。

PostgreSQL允许您将电话号码聚合到一个数组中:

代码语言:javascript
复制
CREATE OR REPLACE FUNCTION getUserById()
RETURNS TABLE (
    id INTEGER,
    name TEXT,
    /* and other columns */
    phone_numbers TEXT[]
)
AS
$$
    select
         users.id,
         users.name,
         /* and other columns */
         -- Remove NULL because you get an array containing just NULL
         -- if user_phones doesn't contain any matching rows.
         array_remove(array_agg(user_phones.phone_number), NULL) as phone_numbers
    from users
    left join user_phones on user_phones.user_id = users.id
    where users.id = 1
    -- Note that grouping by a table's primary key allows you to use
    -- any column from that table in the select in PostgreSQL
    group by users.id
    ;
$$
LANGUAGE SQL
STABLE
;

这要简单得多,也更直观。

如果可以为没有电话号码的用户返回零行,则可以切换到内连接。在这种情况下,您可以放弃array_remove调用。

我还向函数添加了STABLE规范(因为它不修改任何表数据),并将其切换为SQL而不是PGPLSQL (因为它只是一个查询)。这将允许PG更好地优化;特别是,在某些情况下,它可以内联查询和下推过滤器。实际上,你甚至可能不需要一个函数。

票数 1
EN

Stack Overflow用户

发布于 2021-08-04 09:43:38

代码语言:javascript
复制
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;

此外,联系我,如果想实施IT到.NET与C#我解决了这个问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36717138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档