如何将set-returns函数的输出插入表中

时间:2015-06-25 08:29:43

标签: postgresql function row plpgsql set-returning-functions

我有一个带两个参数的函数,从表中返回一些数据。想要将返回的行插入到另一个函数中的临时表(与函数输出结构相同)。

试过这样:

CREATE TEMP TABLE tmp1 (col1 int,  col2 int) ON COMMIT DROP;

WITH x as (select function_name(p1, p2))
    insert into tmp1 select * from x; 

函数RETURNS TABLE(val1 integer, val2 integer)

选择不起作用。

ERROR:  column "col1" is of type integer but expression is of type record
HINT:  You will need to rewrite or cast the expression.

我该怎么办?

3 个答案:

答案 0 :(得分:3)

这样吗?..

insert into tmp1 select * from function_name(p1, p2); 

答案 1 :(得分:1)

这两个查询之间存在重要差异:

select * from function_name(1, 2);
select function_name(1, 2);

第一个查询返回带有两个列的行(因为您的函数返回包含两列的表)。第二个返回带有伪类型记录的一个列的行。

您可以在问题中使用with查询,但是您应该将函数调用放在from子句中:

WITH x as (select * from function_name(p1, p2))
    insert into tmp1 select * from x; 

当然是查询

insert into tmp1 select * from function_name(p1, p2); 

做同样的事情并且更简单。

答案 2 :(得分:0)

根据您的实际查询,在CTE(或子查询)中从函数中获取行类型(而不是使用SELECT * FROM function_name(p1, p2)分解结果)可能有意义也可能没有意义。在某些情况下,避免对函数进行多重评估可能很有用。

但如果你这样做,则需要正确的语法以便稍后分解行类型

WITH x AS (select function_name(p1, p2) f)
INSERT INTO tmp1(col1,  col2)  -- supply a column list
-- SELECT (f).*               -- note the parentheses ...
SELECT (f).val1, (f).val2   -- .... but better yet
FROM   x;

您需要围绕 ( f ) (行类型的隐式列别名)的括号{{ 3}}

并确保在持久化语句中为INSERT的目标提供列列表。如果您稍后更改tmp1的表格布局,如果您不这样做,可能会以惊人的方式中断。
在这种情况下,最好通过名称((f).val1, (f).val2)而不是(f).*

明确定位函数结果的相关列。 顺便说一下,你的函数是taking two parameters的事实与手头的问题无关。只有返回类型的定义很重要。