Как вернуть таблицу из итерации в функции с postgres 11

Следующие функции созданы для ведения домашнего хозяйства в базе данных (PostgreSQL 11.4).

  • entity_with_multiple_taskexec: возвращает список сущностей, для которых необходимо выполнить служебные действия.
  • row_id_to_delete: возвращает кортежи идентификаторов для удаления

Просто для полноты функция, которая отлично работает:

CREATE OR REPLACE  FUNCTION entity_with_multiple_taskexec() 
    RETURNS TABLE(entitykey varchar) AS 
$func$
BEGIN
RETURN QUERY select distinct task.entitykey from
    (select  task.entitykey from task where dtype = 'PropagationTask' group by task.entitykey having count(*) > (select count(*) from conninstance)) more_than_one_entry
inner join task on task.entitykey = more_than_one_entry.entitykey 
inner join taskexec on taskexec.task_id = task.id order by task.entitykey asc;                   
END
$func$  LANGUAGE plpgsql;

Но какая вторая функция, я не могу вернуть таблицу, созданную в результате перебора результатов функции entity_with_multiple_taskexec;

CREATE OR REPLACE  FUNCTION row_id_to_delete() 
    RETURNS TABLE(task_id varchar, taskexec_id varchar) AS 
$func$
DECLARE 
    entityrow RECORD;
    resultset RECORD;
BEGIN
        FOR entityrow IN SELECT entitykey FROM entity_with_multiple_taskexec() LOOP
            insert into resultset select task.id as task_id, taskexec.id as taskexec_id from task  
            inner join taskexec on taskexec.task_id = task.id where taskexec.entitykey = entityrow.entitykey order by taskexec.enddate desc offset 1 
        END LOOP;
    RETURN resultset;
END
$func$ LANGUAGE plpgsql;

Это прерывается следующей ошибкой

ERROR:  syntax error at or near "END"
LINE 12:   END LOOP;

Я пробовал разные подходы. Что было бы хорошим решением для возврата таблицы?


person MemLeak    schedule 14.10.2019    source источник


Ответы (1)


Вам не нужен цикл, просто присоединитесь к функции, как если бы это была таблица.

Также нет необходимости использовать для этого PL/pgSQL, более эффективной будет простая функция language sql.

CREATE OR REPLACE  FUNCTION row_id_to_delete() 
    RETURNS TABLE(task_id varchar, taskexec_id varchar) AS 
$func$
  select task.id as task_id, taskexec.id as taskexec_id 
  from task  
    join taskexec on taskexec.task_id = task.id 
    join entity_with_multiple_taskexec() as mt on mt.entitykey = taskexec.entitykey
  order by taskexec.enddate desc 
  offset 1 
$func$ 
LANGUAGE sql;
person a_horse_with_no_name    schedule 14.10.2019