Можете ли вы вернуть несколько наборов результатов, используя PDO и PostgreSQL? - PullRequest
3 голосов
/ 04 июня 2009

Я хотел бы сгруппировать несколько запросов в одну функцию, которая живет в PostgreSQL. Функция будет запрашиваться с использованием PDO.

Функция:

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

DECLARE
    parentRC refcursor;
    childRC refcursor;

BEGIN

open parentRC FOR
SELECT * FROM parent;
RETURN NEXT parentRC;

open childRC FOR
SELECT * FROM child;
RETURN NEXT childRC;

RETURN;

END;$BODY$
LANGUAGE 'plpgsql' VOLATILE;

ALTER FUNCTION "test_multipe_refcursor"() OWNER TO postgres;

Вот код PHP. «База данных» как одноэлементный класс, который устанавливает обычные свойства соединения, ничего особенного.

  $database = Database::load();
  $sql = "select * from test_multipe_refcursor();";
  $p = $database->query($sql);

  $i = 1;
  do
  {
     $this->set('set' . $i, $p->fetchAll(PDO::FETCH_ASSOC));
     $i++;
  } while ($p->nextRowset());

  $p->closeCursor();

И результат.

 PDOException: SQLSTATE[IM001]: Driver does not support this function: driver does not support multiple rowsets in xxxx.php on line 32

Это может указывать на то, что оно не поддерживается, но, опять же, я не могу найти список, точно определяющий, что именно.

Кому-нибудь удалось заставить это работать?

Ссылки:

Ответы [ 2 ]

4 голосов
/ 06 июня 2009

Поддержка возврата нескольких наборов результатов по-прежнему включена в список задач PostgreSQL , и она определенно не достигнет 8.4. Что касается метода setof refcursors, то, что вы пытаетесь сделать, не работает, потому что функция не возвращает несколько наборов строк - она ​​возвращает один набор строк refcursors. Я не уверен, работает ли использование refcursors на стороне клиента, но я не нахожу это вероятным, даже если протокол клиент-сервер это поддерживает, маловероятно, что PDO имеет API для этого.

Но почему вы пытаетесь вернуть несколько наборов результатов в одном запросе? Вы всегда можете сделать запросы отдельно.

1 голос
/ 03 октября 2009

В нижней части этой страницы документации PostgreSQL есть раздел, описывающий, как вы можете вернуть один или несколько курсоров из функции. По сути, вы заставляете абонента указывать имя курсора (ов) в качестве параметров:

CREATE FUNCTION myfunc(refcursor, refcursor) RETURNS SETOF refcursor AS $$
BEGIN
    OPEN $1 FOR SELECT * FROM table_1;
    RETURN NEXT $1;
    OPEN $2 FOR SELECT * FROM table_2;
    RETURN NEXT $2;
END;
$$ LANGUAGE plpgsql;

-- need to be in a transaction to use cursors.
BEGIN;

SELECT * FROM myfunc('a', 'b');

FETCH ALL FROM a;
FETCH ALL FROM b;
COMMIT;

Страница предназначена для PostgreSQL 8.4, но этот фрагмент документации присутствует, по крайней мере, еще в 8.1 (версия, которую я использую). Как говорится в комментарии, вы должны находиться внутри транзакции, чтобы использовать курсоры, поскольку они неявно закрываются в конце каждой транзакции (то есть в конце каждого оператора, если включен режим автоматической фиксации).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...