Хранимые процедуры (функции), преобразование результата в таблицу

Доброго дня!

Есть следующие исходные данные

CREATE TABLE t_bbb( id int8, PRIMARY KEY ( id ) );
 
INSERT INTO t_bbb( id ) VALUES ( 1 );
INSERT INTO t_bbb( id ) VALUES ( 2 );
INSERT INTO t_bbb( id ) VALUES ( 3 );
INSERT INTO t_bbb( id ) VALUES ( 4 );
INSERT INTO t_bbb( id ) VALUES ( 5 );
 
CREATE OR REPLACE FUNCTION f_bbb( a_ int8 )
RETURNS TABLE( aa int8
             , bb text
             , cc float8 ) AS $$
BEGIN
 raise notice 'f_bbb'; -- показывает сколько раз вызывалась хранимая процедура
 RETURN QUERY SELECT ( a_ + 1 )::int8, 'test'::text, 3.141592::float8;
END;
$$ LANGUAGE plpgsql;

вызываем хранимую процедуру для всех строк таблицы следующим образом:

SELECT ( f_bbb( id ) ).* FROM t_bbb;

возвращается таблица из 3 столбцов и 5 строк, но вместо 5 раз хранимая процедура вызывается 15 раз, в принципе результат не очевидный, но понятный.
SELECT f_bbb( id ) FROM t_bbb;

возвращается таблица из 1 столбца и 5 строк. Хранимая процедура вызывается 5 раз - все как положено. В каждой строке у нас находится строка(row type).

А теперь собственно вопрос - как написать запрос чтобы хранимая процедура вызывалась 5 раз, но при этом возвращалась таблица (3 столбца 5 строк)?
Пробовал создавать тип

CREATE TYPE bbb AS ( aa int8, bb text, cc float8 );
 

пытался привести результат к этому типу
SELECT ( ( b.* )::bbb ).*
FROM ( SELECT f_bbb( id ) FROM t_bbb ) AS b;

но потерпел фиаско

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Если присутствует понятие о

Если присутствует понятие о том, что
SELECT ( f_bbb( id ) ).* FROM t_bbb; = SELECT (f_bbb (id)).aa, (f_bbb (id)).bb, (f_bbb (id)).cc FROM t_bbb; тогда результат должен быть не только понятен но и очивиден.
Есть вариант с функцией

CREATE OR REPLACE FUNCTION f_bbb_( IN a_ int8, out tt bbb) 
            RETURNS setof bbb AS $$
declare
v int8;            
BEGIN
 raise notice 'f_bbb_'; -- показывает сколько раз вызывалась хранимая процедура
 FOR v IN SELECT id FROM t_bbb
 
 loop 
 SELECT * FROM f_bbb(v) INTO tt;
 RETURN next; 
 end loop;
END;
$$ LANGUAGE plpgsql;
/
SELECT * FROM f_bbb_(1);

Решение

Спасибо за ответ, но решение выглядит проще...

условие

CREATE TABLE t_bbb( id int8
                  , txt text
                  , PRIMARY KEY ( id ) );
 
INSERT INTO t_bbb( id, txt ) VALUES ( 1, 'aaa' );
INSERT INTO t_bbb( id, txt ) VALUES ( 2, 'bbb' );
INSERT INTO t_bbb( id, txt ) VALUES ( 3, 'ccc' );
INSERT INTO t_bbb( id, txt ) VALUES ( 4, 'ddd' );
INSERT INTO t_bbb( id, txt ) VALUES ( 5, 'eee' );
 
CREATE OR REPLACE FUNCTION f_bbb_1( a_ int8 )
RETURNS TABLE( aa int8
             , bb text
             , cc float8 ) AS $$
BEGIN
 raise notice 'f_bbb_1';
 RETURN QUERY SELECT ( a_ + 1 )::int8, 'test'::text, 3.141592::float8;
END;
$$ LANGUAGE plpgsql;

Запрос, который выдает требуемое решение

SELECT ( f_b ).* FROM ( SELECT f_bbb_1( id ) AS f_b FROM t_bbb ) AS t_b;

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Back to top

(С) Виктор Вислобоков, 2008-2023