1

我想在 PostgreSQL 中编写一个 plpython3u 函数,它返回一组文本。我偶然发现了一个对我来说很奇怪的难题。根据手册,我可以执行以下操作:

drop schema if exists X cascade;
create schema X;

create type X.greeting AS (
  who text
  );

create function X.greet( how text )
  returns setof X.greeting language plpython3u as $$
  for who in [ 'World', 'PostgreSQL', 'PL/Python' ]:
    yield ( who, )
  $$;

这是一个 Python 函数,它返回一组带有单个文本的行;这么多的作品,我确实得到了预期的输出:

select X.greet( 'helo' );

    greet     
--------------
 (World)
 (PostgreSQL)
 (PL/Python)
(3 rows)

select * from X.greet( 'helo' );

    who     
------------
 World
 PostgreSQL
 PL/Python
(3 rows)

到目前为止,一切都很好。但是,我不想为此目的编写表定义,我想setof record改用,就像在这个例子中一样(碰巧使用整数,但仍然):

create function X.pairs_of_integers_A( out integer, out integer )
  returns setof record language plpython3u as $$
  return [ ( 12, 24, ), ( 36, 48, ), ( 60, 72, ) ]
  $$;

create function X.pairs_of_integers_B( out integer, out integer )
  returns setof record language plpython3u as $$
  for pair in [ ( 12, 24, ), ( 36, 48, ), ( 60, 72, ) ]:
    yield pair
  $$;

select * from X.pairs_of_integers_A();
select * from X.pairs_of_integers_B();

 column1 | column2 
---------+---------
      12 |      24
      36 |      48
      60 |      72
(3 rows)

 column1 | column2 
---------+---------
      12 |      24
      36 |      48
      60 |      72
(3 rows)

现在我们来到有趣的部分。从上面概括,下面的一个或多个公式应该是正确的:要返回一组单个值,要么返回 Python 元组列表、Python 数字列表,要么迭代具有单个值的元组或单个价值观:

create function X.single_integers_A( out integer )
  returns setof record language plpython3u as $$
  return [ ( 12, ), ( 36, ), ( 60, ), ]
  $$;

create function X.single_integers_B( out integer )
  returns setof record language plpython3u as $$
  return [ 12, 36, 60, ]
  $$;

create function X.single_integers_C( out integer )
  returns setof record language plpython3u as $$
  for n in [ ( 12, ), ( 36, ), ( 60, ), ]
    yield n
  $$;

create function X.single_integers_D( out integer )
  returns setof record language plpython3u as $$
  for n in [ 12, 36, 60, ]
    yield n
  $$;

事实证明,以上都没有编译,它们都导致 SQL 解析器抛出函数结果类型必须是整数,因为 OUT 参数。由于我的 SQL 解析器不查看 Python 函数内部,这让我怀疑——</p>

在 PostgreSQL 中,不可能定义一个同时returns setof record具有单个out参数的函数;相反,输出类型必须始终定义为表(或通过类似方式)

谁能纠正我?如果事实证明这是真的,那将真的很烦人。我肯定在某个地方犯了错误吗?

4

1 回答 1

1

您应该只返回一组整数:

create or replace function x.single_integers()
returns setof integer language plpython3u as $$
    return [ 12, 36, 60 ]
$$;

select * from x.single_integers();

 single_integers 
-----------------
              12
              36
              60
(3 rows)    

根据文档(强调添加):

这里的关键点是你必须写 RETURNS SETOF 记录来指示函数返回多行而不是只返回一行。如果只有一个输出参数,则写入该参数的类型而不是记录。

于 2017-11-09T17:14:56.417 回答