PostgreSQL函数或输出多列的存储过程?

A Q*_*ker 12 postgresql stored-procedures plpgsql sql-function

这是我理想的想法.想象一下,我有一个A行的表.

我想要做:

SELECT A, func(A) FROM table
Run Code Online (Sandbox Code Playgroud)

并为输出说4列.

有没有办法做到这一点?我已经看到了自定义类型或任何可以让你得到一个看起来像的结果的东西

A B C D)

但是,如果我能让一个函数返回多个列而不再进行重新分析,那将会非常棒.

有没有什么可以做这样的事情?

bam*_*bam 18

如果函数func仅返回包含3个值的1行,例如:

CREATE OR REPLACE FUNCTION func
(
    input_val       integer,
    OUT output_val1 integer,
    OUT output_val2 integer,
    OUT output_val3 integer
)
AS $$
BEGIN
  output_val1 := input_val + 1;
  output_val2 := input_val + 2;
  output_val3 := input_val + 3;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

然后你执行SELECT a, func(a) FROM table1你会得到:

a       | func
integer | record
========|==========
1       | (2, 3, 4)
2       | (3, 4, 5)
3       | (4, 5, 6)
Run Code Online (Sandbox Code Playgroud)

但是,如果你执行:

SELECT a, (f).output_val1, (f).output_val2, (f).output_val3
FROM (SELECT a, func(a) AS f FROM table1) AS x
Run Code Online (Sandbox Code Playgroud)

你会得到:

a       | output_val1 | output_val2 | output_val3
integer | integer     | integer     | integer
========|=============|=============|=============
1       | 2           | 3           | 4
2       | 3           | 4           | 5
3       | 4           | 5           | 6
Run Code Online (Sandbox Code Playgroud)

或者,使用CTE(公用表表达式),如果执行:

WITH temp AS (SELECT a, func(a) AS f FROM table1)
SELECT a, (f).output_val1, (f).output_val2, (f).output_val3 FROM temp
Run Code Online (Sandbox Code Playgroud)

你还会得到:

a       | output_val1 | output_val2 | output_val3
integer | integer     | integer     | integer
========|=============|=============|=============
1       | 2           | 3           | 4
2       | 3           | 4           | 5
3       | 4           | 5           | 6
Run Code Online (Sandbox Code Playgroud)

注意:您还可以使用以下查询来获得相同的结果:

SELECT a, (f).*
FROM (SELECT a, func(a) AS f FROM table1) AS x
Run Code Online (Sandbox Code Playgroud)

要么

WITH temp AS (SELECT a, func(a) AS f FROM table1)
SELECT a, (f).* FROM temp
Run Code Online (Sandbox Code Playgroud)

  • 或者`SELECT a,(func(a)).*FROM table1`.postgres是疯了 - 我喜欢它.为你+1 +为postgres 100 (12认同)

小智 6

我同意bambam的回答,但是我想指出JackPDouglas SELECT a, (func(a)).* FROM table1在我的测试中更简洁的语法实际上会为每个返回的列执行一次函数,而CTE表达式只会执行一次函数.因此,如果函数需要很长时间才能执行,则首选CTE表达式.

  • +1虽然值得指出,如果函数是"IMMUTABLE"或"STABLE",那么无论如何都无关紧要 (2认同)

pyr*_*lus 0

我想你会想返回一条包含多列的记录?在这种情况下,您可以使用返回类型RECORD。这将允许您返回一个具有任意数量列的匿名变量。您可以在此处找到有关所有不同变量的更多信息:

http://www.postgresql.org/docs/9.0/static/plpgsql-declarations.html

关于返回类型:

http://www.postgresql.org/docs/9.0/static/xfunc-sql.html#XFUNC-OUTPUT-PARAMETERS

如果您想返回具有多列的多条记录,请首先检查是否必须为此使用存储过程。可能可以选择只使用 a VIEW(并使用 WHERE 子句进行查询)。如果这不是一个好的选择,则可以TABLE从版本 9.0 中的存储过程返回 a。