Jef*_*f G 2 sql postgresql function 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;
Run Code Online (Sandbox Code Playgroud)
这些是我迄今为止尝试过的查询:
-- 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
Run Code Online (Sandbox Code Playgroud)
我也尝试将结果类型更改为
myType (CREATE TYPE myType AS (c0 INT, c1 TEXT))SETOF myTypeRECORDSETOF RECORD以上所有表现出相同的行为。
通过调用返回记录、表或记录集的 plpgsql 函数获取多列结果的语法是什么?这个问题听起来很简单,但经过无数次互联网搜索后,我一直无法弄清楚这个问题的语法。我在网上找到的所有问题都使用了语法SELECT * FROM function(),绝对没有有人从另一个查询传递输入参数的例子。
通过调用返回记录、表或记录集的 plpgsql 函数获取多列结果的语法是什么?
这实际上是两三个不同的问题。
table和setof record密切相关(“表”意味着定义明确的行类型,而记录可以定义明确或匿名,需要不同的处理)。
@Kirk为表函数提供了解决方案。
返回单个记录的函数是一种不同的情况。这些允许更多的方式来调用它们。喜欢:
SELECT foo(foreignkey).* -- decomposing is simple for well-known types
FROM sometable
WHERE primarykey = 5;
Run Code Online (Sandbox Code Playgroud)Postgres 查询规划器在那里有一个弱点,并以这种方式多次评估该函数。在 Postgres 9.3 中,LATERAL对于返回多列的昂贵函数,使用连接代替:
SELECT f.*
FROM sometable s
LEFT JOIN LATERAL foo(s.foreignkey) f ON true
WHERE s.primarykey = 5;
Run Code Online (Sandbox Code Playgroud)
细节: