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

发布于 2024-10-26 19:51:22 字数 308 浏览 1 评论 0原文

这就是我理想中想要的。想象一下,我有一个包含行 A 的表。

我想做的是:

SELECT A, func(A) FROM table

输出有 4 列。

有什么办法可以做到这一点吗?我见过关于自定义类型或其他任何可以让你得到看起来像的结果的东西

A,(B,C,D)

但是,如果我能让一个函数返回多列而无需再进行任何欺骗,那就太好了。

有什么东西可以做这样的事情吗?

Here is what I ideally want. Imagine that I have a table with the row A.

I want to do:

SELECT A, func(A) FROM table

and for the output to have say 4 columns.

Is there any way to do this? I have seen things on custom types or whatever that let you sort of get a result that would look like

A,(B,C,D)

But it would be really great if I could have that one function return multiple columns without any more finagling.

Is there anything that can do something like this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

东走西顾 2024-11-02 19:51:22

如果函数 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;

然后执行 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

If the function func returns only 1 row with 3 values, such as:

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;

and you then execute SELECT a, func(a) FROM table1 you'll get:

a       | func
integer | record
========|==========
1       | (2, 3, 4)
2       | (3, 4, 5)
3       | (4, 5, 6)

but, if you execute:

SELECT a, (f).output_val1, (f).output_val2, (f).output_val3
FROM (SELECT a, func(a) AS f FROM table1) AS x

you'll get:

a       | output_val1 | output_val2 | output_val3
integer | integer     | integer     | integer
========|=============|=============|=============
1       | 2           | 3           | 4
2       | 3           | 4           | 5
3       | 4           | 5           | 6

or, using CTE (Common Table Expressions), if you execute:

WITH temp AS (SELECT a, func(a) AS f FROM table1)
SELECT a, (f).output_val1, (f).output_val2, (f).output_val3 FROM temp

you'll also get:

a       | output_val1 | output_val2 | output_val3
integer | integer     | integer     | integer
========|=============|=============|=============
1       | 2           | 3           | 4
2       | 3           | 4           | 5
3       | 4           | 5           | 6

Note: you may also use the following queries to obtain the same results:

SELECT a, (f).*
FROM (SELECT a, func(a) AS f FROM table1) AS x

or

WITH temp AS (SELECT a, func(a) AS f FROM table1)
SELECT a, (f).* FROM temp
凝望流年 2024-11-02 19:51:22

我同意 bambam 的答案,但想指出 JackPDouglas 更简洁的语法 SELECT a, (func(a)).* FROM table1,从我的测试来看,实际上会为每列执行一次该函数返回,而 CTE 表达式只会执行该函数一次。因此,如果函数执行时间较长,则首选 CTE 表达式。

I agree with bambam's answer but would like to point out that JackPDouglas's more succinct syntax SELECT a, (func(a)).* FROM table1, from my tests, would actually execute the function once for each column returned whereas the CTE expression will only execute the function once. So the CTE expression is preferred if the function takes a long time to execute.

顾北清歌寒 2024-11-02 19:51:22

如果函数始终返回 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 。但这看起来又可以使用继承

If the function always returns 3 columns, you can do something like that:

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;

If you can access the table from within a view, maybe you can create a view in some way

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

then it's just a SELECT * FROM v. But again this looks like Inheritance could be used.

Oo萌小芽oO 2024-11-02 19:51:22

我想你会想返回一条包含多列的记录?在这种情况下,您可以使用返回类型 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

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

I think you will want to return a single record, with multiple columns? In that case you can use the return-type RECORD for example. This will allow you to return an anonymous variable with as many columns as you want. You can find more information about all the different variables here:

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

And about return types:

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

If you want to return multiple records with multiple columns, first check and see if you have to use a stored procedure for this. It might be an option to just use a VIEW (and query it with a WHERE-clause) instead. If that's not a good option, there is the possibility of returning a TABLE from a stored procedure in version 9.0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文