在PL / pgSQL中声明表类型的变量


8

我想知道是否有一种方法可以在PL / pgSQL中声明类型表的变量来保存查询结果?例如,我如何表达这样的东西:

q1 = select * from foo;
q2 = select * from bar;
for t1 in q1:
  for t2 in q2:
    -- do something with t1 and t2

我研究了return next构造,但似乎只能处理返回值。


2
PL / SQL => Oracle,PgPL / SQL => PostgreSQL。您正在使用哪一个?

@Mat:是PL / pgSQL,顺便说一句。
Erwin Brandstetter

Answers:


12

PostgreSQL中,每个表名都会自动用作行类型(又称复合类型)的类型名- 不是表类型,Postgres中没有“表类型”或“表变量”(但有类型表)。
因此,您可以在中声明该类型的变量PL/pgSQL

CREATE FUNCTION foo()
 RETURNS void LANGUAGE plpgsql AS
$func$
DECLARE
  q1 foo;  -- "foo" ...
  q2 bar;  -- ... and "bar" are existing (visible) table names
BEGIN

FOR q1 IN 
   SELECT * from foo
LOOP
   FOR q2 IN 
      SELECT * from bar
   LOOP
       -- do something with q1 and q2
       -- since q1 and q2 are well known types, you can access columns
       -- with attribute notation. Like: q1.col1
   END LOOP;
END LOOP;

END
$func$

一个FOR循环可与内置的光标。plpgsql 中也有显式游标

您也可以只声明泛型类型的变量record。自动分配时可以采用任何行类型。但适用特殊规则。请务必点击链接并阅读手册的章节!

虽然使用函数return通常很方便SETOF <table name>,但是返回SETOF record并不方便。系统不知道函数以这种方式返回什么,因此您必须在每次调用时添加一个列定义列表。真是痛苦 有关手册中表格功能的详细信息。

但是,通常使用普通SQL会有更有效的解决方案。循环是最后的手段,当您可以在一次扫描中执行某些操作时,您将需要在纯SQL中进行多次扫描。


2
另请注意,如果您想返回表类型,您可以说类似CREATE FUNCTION footest() RETURNS SETOF foo LANGUAGE PLPGSQL AS $$...
Chris Travers

为什么如果我们可以创建表而不对复合类型施加限制(没有约束等),那么为什么我们完全具有“复合类型”功能?我看到的使用复合类型的唯一有意义的方法是从函数中返回几个(或几个)参数,而不是为此创建整个表。
SaneDeveloper
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.