поддерживает ли node-postgres несколько наборов результатов

У меня есть функция PostgresQL, которая возвращает несколько наборов результатов. Я могу без проблем извлечь эти наборы результатов в .net (поэтому я знаю, что моя функция работает правильно), но у меня возникают проблемы с этим с node-postgres.

Объект результата возвращает массив из 7 элементов, который соответствует количеству возвращенных наборов данных.

В Node каждая из 7 строк просто содержит строку <unnamed portal 1>.

connection.query("BEGIN");
connection.query({text: "SELECT getoperationaldatasetmodel($1)", values : [clientid]}, function(err, results) {


  if (err) {
    connection.query("COMMIT");
    self.pool.release(connection);
    callback(err);
  }
  else {
    var opsDataset = null;
    var rows = results.rows;
    // this returns 7 rows but the rows do not contain data but rather the name of the dataset.
  }

Итак: поддерживает ли node-postgres несколько наборов результатов, и если да, какие предложения по извлечению?

РЕДАКТИРОВАТЬ: Вот код, который я использовал с node-postgres, если кому-то еще понадобится его использовать в будущем.

// must wrap in a transaction otherwise won't be able to see the multiple sets.
connection.query("BEGIN");
connection.query({text: "SELECT myfunction($1)", values : [clientid]}, function(err, results) {

  if (err) {

     // handle error here
     connection.query("COMMIT;");
  }
  else {

    connection.query('FETCH ALL FROM "<unnamed portal 1>"',  function(err, r1) {
        // r1.rows will contain the data for the first refcursor
    });
    connection.query('FETCH ALL FROM "<unnamed portal 2>"',  function(err, r2) {
        // r2.rows will contain the data for the second refcursor
    });

    // remember to handle the closure of the transaction

});

person AlexGad    schedule 24.08.2012    source источник
comment
stackoverflow.com/questions/6674787 /   -  person Craig Ringer    schedule 24.08.2012
comment
stackoverflow.com/questions/11135815/   -  person Craig Ringer    schedule 24.08.2012
comment
... ни один из них на самом деле не дает ответов о том, как получить от refcursor. Извиняюсь. Похоже, что это либо плохо документировано, либо очень сложно извлекать строки из refcursor в SQL.   -  person Craig Ringer    schedule 24.08.2012
comment
Только что связался с Брайаном Карлсоном, создателем, и он сказал, что ничего не сделал для поддержки рекурсоров. Я собираюсь поднять проблему GIT, чтобы посмотреть, можно ли ее решить.   -  person AlexGad    schedule 24.08.2012
comment
Алекс, а зачем вам изначально нужны множественные наборы результатов? Вы застряли с функцией postgres? Или вы, как и я, предположили, что будет быстрее выполнять все запросы к БД за один раз и возвращать все результаты в пакете, чем выполнять несколько циклов от сервера к БД? Если второе, подход с несколькими наборами результатов оказался быстрее?   -  person poshest    schedule 29.10.2014


Ответы (1)


ОБНОВЛЕНИЕ: см. этот превосходный учебник, в котором объясняется, как получать и управлять рекурсоры.


Поскольку node-postgres не распознает рекурсоры, которые вы возвращаете, как дескрипторы набора результатов, вполне вероятно, что он не поддерживает множественные наборы результатов из PostgreSQL. Это достаточно справедливо, поскольку PostgreSQL на самом деле не поддерживает множественные наборы результатов, они просто эмулируются с помощью refcursors.

Вы можете FETCH из refcursor с помощью команд курсора уровня SQL команд курсора уровня SQL, хотя документация на него убогая. Для этого вам не нужно использовать PL/PgSQL обработку курсора. Только что:

FETCH ALL FROM "<unnamed portal 1>";

Обратите внимание на двойные кавычки, которые важны. Замените имя refcursor, возвращаемое вашей функцией, на <unnamed portal 1>.

Также обратите внимание, что транзакция, которая создала refcursor, должна быть открыта, если курсор не был создан WITH HOLD. Курсоры, отличные от HOLD, закрываются, когда транзакция фиксируется или откатывается.

Например, для фиктивной функции, возвращающей refcursor:

CREATE OR REPLACE FUNCTION dummy_cursor_returning_fn() RETURNS SETOF refcursor AS $$
DECLARE
    curs1 refcursor;
    curs2 refcursor;
BEGIN
    OPEN curs1 FOR SELECT generate_series(1,4);
    OPEN curs2 FOR SELECT generate_series(5,8);
    RETURN NEXT curs1;
    RETURN NEXT curs2;
    RETURN;
END;
$$ LANGUAGE 'plpgsql';

... который возвращает набор курсоров, вы можете получить результаты, передав имена порталов в FETCH, например:

regress=# BEGIN;
BEGIN
regress=# SELECT dummy_cursor_returning_fn();
 dummy_cursor_returning_fn 
---------------------------
 <unnamed portal 7>
 <unnamed portal 8>
(2 rows)

regress=# FETCH ALL FROM "<unnamed portal 7>";
 generate_series 
-----------------
               1
               2
               3
               4
(4 rows)

regress=# FETCH ALL FROM "<unnamed portal 8>";
 generate_series 
-----------------
               5
               6
               7
               8
(4 rows)

regress=# 
person Craig Ringer    schedule 24.08.2012
comment
Абсолютно потрясающе!!! Полностью решил мою проблему. Я собираюсь предоставить код, который я использовал с node-postgres, чтобы специально решить его для других, но я отметил ваш ответ как правильный. Спасибо, определенно помогло мне сохранить те волосы, которые у меня остались ;). - person AlexGad; 24.08.2012