复合类型的循环作为存储过程输入PostgreSQL

时间:2017-04-18 19:17:16

标签: arrays postgresql stored-procedures types plpgsql

我通过传递一个类型来创建一个存储过程,并在该过程中执行一个循环,以便我可以插入每个信息类型

这是我的类型

 create type leketo as(id integer, name text);

将行插入我的类型

的函数
 CREATE OR REPLACE FUNCTION getLeketo()
  RETURNS SETOF leketo AS
$BODY$
declare
l leketo;
begin

l.id := 1;
l.name := 'One';
return next l;

l.id := 2;
l.name := 'Two';
return next l;


l.id := 3;
l.name := 'Three';
return next l;


l.id := 4;
l.name := 'Four';
return next l;

l.id := 5;
l.name := 'Five';
return next l;

end
$BODY$
  LANGUAGE plpgsql VOLATILE;

运行该函数会将此返回给我

select * from getLeketo()

1  One 
2  Two 
3  Three 
4  Four 
5  Five 

在此过程中,我们将遍历所有行

CREATE OR REPLACE FUNCTION loopLeketo(pl leketo)
  RETURNS void AS
$BODY$
declare
l leketo;
begin

 for l in (select * from pl) loop
  raise notice '----------------------------------------';
  raise notice 'id=%, name=%', l.id, l.name;
 end loop;
end
$BODY$
  LANGUAGE plpgsql VOLATILE;

如果我试试这个,我收到以下消息

DO $$
declare
l leketo;
begin
select * from getLeketo() into l;
PERFORM loopLeketo(l);
end$$;

错误:关系“pl”不存在

1 个答案:

答案 0 :(得分:1)

您收到该错误消息,因为参数(在您的情况下为pl)不能出现在查询的FROM子句中,因此PostgreSQL会将pl解释为表名。< / p>

更深层次的问题是,您尝试将一组值分配给单个变量,这将无效。您的SELECT ... INTO语句只会将第一个结果存储在变量l中。

您没有告诉我们您真正希望实现的目标,但我可以为您展示的问题考虑两种方法:

  1. 逐个处理查询结果。 PL / pgSQL代码看起来像这样:

    DEFINE
       l leketo;
    BEGIN
       FOR l IN SELECT * FROM getleketo() LOOP
          RAISE NOTICE 'id=%, name=%', l.id, l.name;
       END LOOP;
    END;
    
  2. getleketo()定义为RETURNS SETOF leketo,但定义为RETURNS refcursor并让它返回结果的光标。然后,您可以将整个查询结果分配给类型为refcursor的变量,并将其用作loopleketo函数的参数。

    有关详细信息,请参阅the documentation