Как вставить вывод функции set-return в таблицу

У меня есть функция, принимающая два параметра, возвращает некоторые данные из таблиц. Хотите вставить возвращенные строки во временную таблицу (с той же структурой, что и вывод функции) в другой функции.

Пробовал так:

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.

Что мне делать?


person Raghu    schedule 25.06.2015    source источник
comment
Спасибо за ответы. Я могу сделать это, используя функцию select * from .. !!   -  person Raghu    schedule 26.06.2015


Ответы (3)


а вот так?..

insert into tmp1 select * from function_name(p1, p2); 
person Vao Tsun    schedule 25.06.2015

Между этими двумя запросами есть важное различие:

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

делает то же самое и проще.

person klin    schedule 25.06.2015

В зависимости от вашего фактического запроса может иметь или не иметь смысл извлекать тип строки из функции (вместо разложения результата с помощью SELECT * FROM function_name(p1, p2)) в CTE (или подзапросе). В некоторых контекстах может быть полезно избегать многократного вычисления функции.

Но если вы это сделаете, вам понадобится правильный синтаксис, чтобы позже разложить тип строки на столбец:

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) (неявный псевдоним столбца для типа строки) для доступ к столбцам составного типа (типа строки).

И обязательно укажите список столбцов для цели INSERT в сохраняемых операторах. Если вы этого не сделаете, это может неожиданно сломаться, если вы позже измените макет таблицы tmp1.
В этом случае, вероятно, также лучше нацеливать соответствующие столбцы результата функции явно по имени ((f).val1, (f).val2), а не (f).*

Кстати, тот факт, что ваша функция taking two parameters, не имеет отношения к рассматриваемой проблеме. Имеет значение только определение типа возвращаемого значения.

person Erwin Brandstetter    schedule 25.06.2015