这是我理想中想要的。想象一下,我有一张带有 A 行的表格。
我想要做:
SELECT A, func(A) FROM table
并且输出有 4 列。
有没有办法做到这一点?我已经看到有关自定义类型或任何可以让您获得看起来像的结果的东西
A B C D)
但是,如果我可以让一个函数返回多列而不需要更多的麻烦,那就太好了。
有什么可以做这样的事情吗?
这是我理想中想要的。想象一下,我有一张带有 A 行的表格。
我想要做:
SELECT A, func(A) FROM table
并且输出有 4 列。
有没有办法做到这一点?我已经看到有关自定义类型或任何可以让您获得看起来像的结果的东西
A B C D)
但是,如果我可以让一个函数返回多列而不需要更多的麻烦,那就太好了。
有什么可以做这样的事情吗?
如果函数func只返回 1 行 3 个值,例如:
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;
然后你执行SELECT a, func(a) FROM table1
你会得到:
a | func
integer | record
========|==========
1 | (2, 3, 4)
2 | (3, 4, 5)
3 | (4, 5, 6)
但是,如果你执行:
SELECT a, (f).output_val1, (f).output_val2, (f).output_val3
FROM (SELECT a, func(a) AS f FROM table1) AS x
你会得到:
a | output_val1 | output_val2 | output_val3
integer | integer | integer | integer
========|=============|=============|=============
1 | 2 | 3 | 4
2 | 3 | 4 | 5
3 | 4 | 5 | 6
或者,使用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
您还将获得:
a | output_val1 | output_val2 | output_val3
integer | integer | integer | integer
========|=============|=============|=============
1 | 2 | 3 | 4
2 | 3 | 4 | 5
3 | 4 | 5 | 6
注意:您也可以使用以下查询来获得相同的结果:
SELECT a, (f).*
FROM (SELECT a, func(a) AS f FROM table1) AS x
或者
WITH temp AS (SELECT a, func(a) AS f FROM table1)
SELECT a, (f).* FROM temp
我同意 bambam 的回答,但想指出 JackPDouglas 更简洁的语法SELECT a, (func(a)).* FROM table1
,根据我的测试,实际上会为返回的每一列执行一次函数,而 CTE 表达式只会执行一次函数。因此,如果函数执行时间较长,则首选 CTE 表达式。
如果函数总是返回 3 列,你可以这样做:
CREATE TYPE sometype AS (b INT, c TEXT, d TEXT);
CREATE OR REPLACE FUNCTION func(a TEXT) RETURNS SETOF sometype AS $$
BEGIN
RETURN QUERY EXECUTE 'SELECT b, c, d FROM ' || a;
END;
$$ LANGUAGE plpgsql;
SELECT a, (f).b, (f).c, (f).d
FROM (SELECT a, func(a) AS f FROM table) x;
如果您可以从视图中访问表,也许您可以以某种方式创建视图
CREATE VIEW v AS
SELECT 'tab1' AS a, b, c, d FROM tab1 WHERE 'tab1' IN (SELECT a FROM table)
UNION
SELECT 'tab2' AS a, b, c, d FROM tab2 WHERE 'tab2' IN (SELECT a FROM table)
UNION
SELECT 'tab3' AS a, b, c, d FROM tab3 WHERE 'tab3' IN (SELECT a FROM table);
那么它只是一个SELECT * FROM v
. 但这看起来像可以使用继承。
我想你会想要返回一条记录,多列?在这种情况下,您可以使用返回类型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。