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

JRR*_*JRR 9 postgresql stored-procedures plpgsql

我想知道是否有办法在 PL/pgSQL 中声明表类型的变量来保存查询结果?例如,我如何表达如下内容:

q1 = select * from foo;
q2 = select * from bar;
for t1 in q1:
  for t2 in q2:
    -- do something with t1 and t2
Run Code Online (Sandbox Code Playgroud)

我查看了 return next 构造,但它似乎只能处理返回值。

Erw*_*ter 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$
Run Code Online (Sandbox Code Playgroud)

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

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

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

但是,通常使用纯 SQL 有更有效的解决方案。循环是最后的手段,当您可以在一次扫描中完成在纯 SQL 中需要多次扫描的事情时。

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