调用Postgres函数返回记录,传入查询结果

时间:2014-06-05 18:15:05

标签: sql function postgresql plpgsql postgresql-9.3

问题是我需要运行一个查询(仅在运行时已知)来确定我的函数的输入参数,它需要返回一个结果。例如,我想写:

CREATE FUNCTION foo(inputKey INT) RETURNS TABLE (c0 INT, c1 TEXT) AS $$
    BEGIN
        -- Do something with inputKey to compute and return result
    END;
$$ LANGUAGE PLPGSQL;

这些是我迄今为止尝试过的查询:

-- Doesn't even run (exception)
SELECT * FROM foo(SELECT foreignKey FROM someTable WHERE primaryKey = 5);

-- Runs, but returns a single column with all columns listed in it's value
SELECT foo(foreignKey) FROM someTable WHERE primaryKey = 5;

-- Same problem as previous
SELECT * FROM (SELECT foo(foreignKey) FROM someTable WHERE primaryKey = 5) AS a

我也尝试将结果类型更改为

  • myType (CREATE TYPE myType AS (c0 INT, c1 TEXT))
  • SETOF myType
  • RECORD
  • SETOF RECORD

以上所有都表现出相同的行为。

通过调用返回记录,表或setof记录的plpgsql函数来获取多列结果的语法是什么?这个问题听起来很简单,但是经过无数的互联网搜索,我无法弄清楚这个问题的语法。我在网上使用语法SELECT * FROM function()的所有问题,绝对没有人从另一个查询传递输入参数的例子。

2 个答案:

答案 0 :(得分:4)

  

通过调用plpgsql获取多列结果的语法是什么   返回记录,表或setof记录的函数?

这实际上是两三个不同的问题。

  • tablesetof record密切相关(“表”表示定义明确的行类型,而记录可以很好地定义或匿名,需要不同的处理)。
    对于函数,@Kirk provided a solution

  • 返回单条记录的函数是另一种情况。那些允许更多的方式来调用它们。像:

    SELECT foo(foreignkey).*  -- decomposing is simple for well-known types
    FROM   sometable
    WHERE  primarykey = 5;
    

Postgres查询规划器在那里有一个弱点,并以这种方式多次评估该函数。在Postgres 9.3中,使用LATERAL连接代替返回多列的昂贵函数:

    SELECT f.*
    FROM   sometable s
    LEFT   JOIN LATERAL foo(s.foreignkey) f ON true
    WHERE  s.primarykey = 5;

详细说明:

答案 1 :(得分:2)

你几乎到了那里:

SELECT * FROM foo((SELECT foreignKey FROM someTable WHERE primaryKey = 5));

请注意额外的括号设置以创建子查询。返回值将用作函数参数。

调用函数后,结果将会扩展。