Postgresql plpgsql 多行循环

Posted

技术标签:

【中文标题】Postgresql plpgsql 多行循环【英文标题】:Postgresql plpgsql multiple row loop 【发布时间】:2015-10-13 11:43:52 【问题描述】:

我正忙于为 PostgreSQL 重写 Informix 存储过程 数据库,我被困在可能很明显的事情上 所有了解 PostgreSQL 的人。

我的 sql 脚本如下

-- ensure type and function get created
drop type if exists tp_users cascade;
drop function if exists sp_cmplist();

-- create type
create type tp_users as (
    us_id       char(30),
    us_status   char(1)
);

create function sp_cmplist()
    returns tp_users as $$
declare
    lr_users   tp_users;
begin

    for lr_users in
        select users.us_id, users.us_status
        from users
    loop
        return lr_users;
    end loop;

end

$$ language 'plpgsql';

select sp_cmplist();

这只是一个从虚拟用户表中选择的虚拟脚本,但我如何使用这个带有光标或循环的脚本来确保返回所有结果?

【问题讨论】:

更适合:dba.stackexchange.com 我之前尝试过数据库管理员社区,但他们用诸如此类的问题将我拒之门外,说它不够专业或类似的问题 *** 是个好地方——plpgsql 是开发者主题 【参考方案1】:

此代码有效:

CREATE TABLE foo(a int);
INSERT INTO foo VALUES(10),(20);

CREATE OR REPLACE FUNCTION retfoo()
RETURNS SETOF foo AS $$
BEGIN
  RETURN QUERY SELECT * FROM foo;
  RETURN;
END;
$$ LANGUAGE plpgsql;

postgres=# SELECT * FROM retfoo();
┌────┐
│ a  │
├────┤
│ 10 │
│ 20 │
└────┘
(2 rows)

时间:1.143 毫秒

【讨论】:

【参考方案2】:

我可能已经用以下内容回答了我自己的问题

drop type if exists tp_users cascade;
drop function if exists sp_cmplist();

create type tp_users as (
    us_id        text,
    us_status    text,
    lv_nothing   text,
    lv_cnt       int
);

create function sp_cmplist()
    returns setof tp_users as $$
declare
    lr_users   tp_users;
    lv_cnt     int;
begin

    lv_cnt := 0;

    for lr_users in
        select users.us_id, users.us_status
        from users
    loop

        -- increment this counter for testing purposes
        lv_cnt              := lv_cnt + 1;

        lr_users.lv_nothing := 'yupy';
        lr_users.lv_cnt     := lv_cnt;

        return next lr_users;

    end loop;

    return;

end

$$ language 'plpgsql';

select * from sp_cmplist();

这似乎工作得很好

【讨论】:

对于这个请求,您不需要for 循环。它比RETURN QUERY SELECT use_id, us_status, 'yupy', row_number() over () FROM users; 慢。简单查询可以解决的问题,应该通过简单查询来解决。 通常我会这样做,返回的变量是一个表,但这个例子只是一个虚拟查询,真正的查询是使用多个单独的选择并比较结果并建立数据循环中的返回,我认为我无法通过一次选择轻松地做到这一点

以上是关于Postgresql plpgsql 多行循环的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL - 继续 unique_violation (plpgsql)

在 postgresql 中使用 plpgsql 有啥好处

Postgresql - 从 plpgsql 函数返回记录 []

从 plpgsql 函数返回多行

如何在 PostgreSQL 9.2 中分析 plpgsql 函数

Postgresql 10 plpgsql 测试列是不是存在于记录变量中