【问题标题】:Call a Postgres function that returns a record, passing in the result of a query调用返回记录的 Postgres 函数,传入查询结果
【发布时间】:2014-06-05 18:15:05
【问题描述】:

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

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

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

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

【问题讨论】:

  • SELECT foo(foreignKey).* FROM someTable WHERE primaryKey = 5; 怎么样?这可能会将记录取消嵌套到列中 (SQLFiddle example)
  • @TomasGreif :语法是 SELECT (foo(foreignKey)).* FROM someTable WHERE primaryKey = 5;不幸的是,这将导致为返回表中的每一列调用该函数。

标签: sql function postgresql plpgsql postgresql-9.3


【解决方案1】:

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

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

  • 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;

详情:

【讨论】:

  • 这是真的。我提供了我认为 OP 暗示的答案。
【解决方案2】:

你快到了:

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

注意用于创建子查询的额外括号集。返回值将用作函数参数。

函数调用后会展开结果。

【讨论】:

    猜你喜欢
    • 2020-02-03
    • 1970-01-01
    • 2020-04-15
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多