Функция PostgreSQl возвращает несколько наборов динамических результатов

У меня есть старая процедура MSSQL, которую нужно перенести в функцию PostgreSQL. В основном процедура SQL состоит из CURSOR над оператором select. Для каждого объекта курсора у меня есть три оператора выбора на основе текущего вывода курсора.

FETCH NEXT FROM @cursor INTO @entityId
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT * FROM table1 WHERE col1 = @entityId
SELECT * FROM table2 WHERE col2 = @entityId
SELECT * FROM table3 WHERE col3 = @entityId
END

Таблицы из операторов SELECT имеют разные столбцы.

Я знаю, что PostgreSQL использует refcursor для возврата нескольких наборов результатов, но вопрос в том, можно ли открывать и возвращать несколько динамических рефкурсоров внутри цикла?

Поставщик данных Npgsql .NET используется для обработки результатов.

Тестовый код Postgres с одним курсором внутри цикла:

CREATE OR REPLACE FUNCTION "TestCursor"(refcursor) 
RETURNS SETOF refcursor AS
$BODY$

DECLARE
    entity_id integer;  
BEGIN

    FOR entity_id IN SELECT "FolderID" from "Folder"
    LOOP
        OPEN $1 FOR SELECT * FROM "FolderInfo" WHERE "FolderID" = entity_id;
        RETURN NEXT $1;
        CLOSE $1;   
    END LOOP;
END;

$BODY$
LANGUAGE 'plpgsql' VOLATILE;

Затем тестовый код:

BEGIN;
SELECT * FROM "TestCursor"('c');
FETCH ALL IN c;
COMMIT;

Вывод SELECT * FROM "TestCursor"('c'); похож на скриншот:введите здесь описание изображения Затем, когда я пытаюсь получить данные, я получаю сообщение об ошибке: ERROR: cursor "c" does not exist


person Trasnea Daniel    schedule 03.11.2015    source источник
comment
PostgreSQL не поддерживает хранимые процедуры, поэтому вы можете возвращать только один результат за раз.   -  person Abhishek Ginani    schedule 03.11.2015
comment
Возможно. Проверьте этот сообщение.   -  person Trasnea Daniel    schedule 03.11.2015
comment
Не могли бы вы уточнить, что выбрано из 3 таблиц и как вы хотите, чтобы оно было возвращено? Например, refcursor не является результирующим набором. Если столбцы трех таблиц идентичны по типу данных, вы можете UNION объединить запросы в один, а затем вернуть этот набор результатов.   -  person Patrick    schedule 03.11.2015
comment
Таблицы имеют разные столбцы, поэтому UNION использовать нельзя.   -  person Trasnea Daniel    schedule 03.11.2015
comment
Это не дубликат. Я видел этот пост до того, как задал этот вопрос. Проблема здесь в том, что рекурсоры открываются-закрываются внутри LOOP. Когда вы выполните эту функцию, вы получите список курсоров, и я не знаю, как получить от них данные.   -  person Trasnea Daniel    schedule 03.11.2015


Ответы (1)


Вы можете эмулировать его через SETOF refcursor. Но это не очень хорошая идея. Этот шаблон T-SQL плохо поддерживается в Postgres и должен быть запрещен, когда это возможно. Функции поддержки PostgreSQL — функция может возвращать скаляр, вектор или отношение. Это все. Обычно в 90% случаев удается переписать процедуры T-SQL для очистки функций PostgreSQL.

person Pavel Stehule    schedule 03.11.2015