【问题标题】:Postgresql plpgsql multiple row loopPostgresql plpgsql 多行循环
【发布时间】: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
  • 我之前尝试过数据库管理员社区,但他们用诸如此类的问题将我拒之门外,说它不够专业或类似的问题
  • stackoverflow 是个好地方——plpgsql 是开发者主题

标签: postgresql loops stored-procedures cursor 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; 慢。简单查询可以解决的问题,应该通过简单查询来解决。
    • 通常我会这样做,返回的变量是一个表,但这个例子只是一个虚拟查询,真正的查询是使用多个单独的选择并比较结果并建立数据循环中的返回,我认为我无法通过一次选择轻松地做到这一点
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    相关资源
    最近更新 更多