【问题标题】:does node-postgres support multiple resultsetsnode-postgres 是否支持多个结果集
【发布时间】:2012-08-19 13:37:30
【问题描述】:

我有一个返回多个结果集的 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

});

【问题讨论】:

  • ...它们都没有真正提供有关如何从 refcursor 获取的答案。对不起。在 SQL 中从refcursor 中获取行看起来要么文档严重不足,要么真的很痛苦。
  • 刚刚与创建者 Brian Carlson 核实过,他说他没有做任何事情来支持 recursors。我将提出一个 GIT 问题,看看是否可以解决。
  • Alex,你为什么一开始想要多个结果集?您是否坚持使用 postgres 功能?或者您是否像我一样认为一次完成所有数据库查询并以捆绑包的形式返回所有结果会比多次服务器到数据库往返更快?如果是后者,“多结果集方法”最终会更快吗?

标签: node.js postgresql node-postgres


【解决方案1】:

更新:请参阅 this excellent tutorial,了解如何获取和管理 refcursor。


由于 node-postgres 无法识别您作为结果集句柄返回的 refcursor,它似乎不支持来自 PostgreSQL 的多个结果集。这很公平,因为 PostgreSQL 也不真正支持多个结果集,它们只是用 refcursors 进行模拟。

您可以通过 SQL 级游标命令 SQL-level cursor commandsrefcursorFETCH,尽管它的文档很糟糕。您不需要使用PL/PgSQL 游标处理来执行此操作。只是:

FETCH ALL FROM "<unnamed portal 1>";

注意双引号,这很重要。用你的函数返回的引用名称替换&lt;unnamed portal 1&gt;

还要注意,除非创建了光标WITH HOLD,否则创建引用光标的事务必须仍处于打开状态。事务提交或回滚时关闭非HOLD 游标。

例如,给定虚拟的 refcursor-returning 函数:

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=# 

【讨论】:

  • 太棒了!!!彻底解决了我的问题。我将提供我与 node-postgres 一起使用的代码来专门为其他人解决它,但我已将您的答案标记为正确的答案。谢谢,绝对帮助我保留了我剩下的头发;)。
猜你喜欢
  • 2013-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多