我有一个带两个参数的函数,从表中返回一些数据。想要将返回的行插入到另一个函数中的临时表(与函数输出结构相同)。
试过这样:
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.
我该怎么办?
答案 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
的事实与手头的问题无关。只有返回类型的定义很重要。