【发布时间】:2015-08-13 13:21:46
【问题描述】:
我正在尝试创建一个函数,该函数可以从表中一一获取行,并为每一行为不同的表生成 1 行或更多行。例如,让我们以这个玩具函数为例(注意:在这个例子中,输入和输出具有相同的字段,但在我原来的问题中,字段是不同的):
CREATE OR REPLACE FUNCTION toy_function( a integer, b integer )
RETURNS TABLE( x integer, y integer ) AS $$
BEGIN
FOR i IN 1..2 LOOP
x := a + b + i;
y := a * b * i;
RETURN NEXT;
END LOOP;
END;
$$ LANGUAGE plpgsql;
给出预期的输出:
SELECT * FROM toy_function( 10, 20 );
x | y
----+-----
31 | 200
32 | 400
(2 rows)
但如果我将表中的行传递给它,如下所示:
WITH data AS (
SELECT 1 * i AS a, 2 * i AS b
FROM GENERATE_SERIES( 1, 3, 1 ) as i
)
SELECT
toy_function( a, b )
FROM
data;
我得到一个记录列表,而不是我之前得到的列:
toy_function
--------------
(4,2)
(5,4)
(7,8)
(8,16)
(10,18)
(11,36)
(6 rows)
将函数调用包装在 ().* 中会返回单独的列,但会大大降低查询速度(在我原来的问题中,它从 2 秒变为 6 秒!)。
我也尝试在子查询中传递输入数据,但失败并出现我不太明白的错误:
WITH data AS (
SELECT 1 * i AS a, 2 * i AS b
FROM GENERATE_SERIES( 1, 3, 1 ) as i
)
SELECT
*
FROM
toy_function(( SELECT * FROM data));
ERROR: subquery must return only one column
LINE 8: toy_function(( SELECT * FROM data));
有没有办法做到这一点?要将“数据”中的行一一传递给函数,并从函数中取出一个带有显式列的表?
【问题讨论】:
标签: postgresql plpgsql