【问题标题】:Fetch multiple Refcursor in node js from postgres db (using pg-promise)从 postgres db 获取节点 js 中的多个 Refcursor(使用 pg-promise)
【发布时间】:2017-10-20 10:48:56
【问题描述】:

我需要从 Nodejs 中的 pg 函数中获取多个游标。

我在 PG 中尝试了两种函数编写方法,如下链接所述: http://www.sqlines.com/postgresql/how-to/return_result_set_from_stored_procedure

在 PG 管理中|||查询工具我可以通过给出它的名称来查看多个游标的输出。 我想从节点 js 应用程序中获取相同的内容,我正在使用“pg-promise”。

选项-1

 db.func('get_data',
    [
        name,
        key
    ])
    .then(dbResult => {
        console.log(" RES 1" + dbResult);               
    }).catch(error => {
        console.log(error);
        throw error;
    });

选项 2

var retCursor1 = {};
var retCursor2 = {};
db.func('get_data',
    [
        name,
        key,
        retCursor1,
        retCursor2,
    ])
    .then(dbResult => {
        console.log(" RES 1" + dbResult);               
        console.log(" RES 2" + retCursor1);               
        console.log(" RES 3" + retCursor2);               
    }).catch(error => {
        console.log(error);
        throw error;
    });

get_data PG 函数将返回 2 个 refCursors。

但是没有运气,有人可以建议在 Node js 中获取多个光标的最佳方法是什么。

【问题讨论】:

  • 您作为参数传递给db.func 的内容只能是输入参数。该语法不支持输出参数。
  • 在 option-2 中输入前 2 个元素,但 refcursor1 和 2 被命名为游标,期望输出记录在 DB 中。我从 pg admin 尝试过的同类,我得到的结果和查询如下...... 'select get_data('SFO', 'FRA', 'result1', 'result2');获取所有“结果1”; FETCH all IN "result2";'
  • 这不能直接与 pg-promise 一起工作,它需要使用游标的特殊方法。另见:stackoverflow.com/questions/12101773/…
  • 最好是重新设计函数,以便您可以使用这种方法:github.com/vitaly-t/pg-promise/wiki/…
  • db.query( { text: "select get_data($1, $2, $3)", values: [ a, b, c ] }, function (err, r) { if (err) { db.query("COMMIT;"); } else { db.query('FETCH ALL FROM ""', function (err, r1) { }); db.query('FETCH ALL FROM ""', function (err, r2) { }); db.query("COMMIT;"); }

标签: javascript node.js postgresql pg-promise


【解决方案1】:

来自pg-promise的作者。


很遗憾,底层驱动程序node-postgres 不支持FETCH 查询。

他们建议使用单独的模块 - node-pg-cursor,我尝试过,但无法使其适用于您的情况,请参阅我打开的问题:https://github.com/brianc/node-pg-cursor/issues/34

我的建议是尽量避免它,不要从函数返回任何游标,或者至少不要从 Node.js 中直接调用那些游标。

如果您考虑性能和效率,那么最好的方法是通过multi 方法在单个命令中执行多个SELECT 查询,该方法是在pg-promise v7.0.0 中添加的:

db.multi('SELECT * FROM users WHERE name LIKE ${user.name};' +
    'SELECT * FROM products WHERE price BETWEEN ${price.min} AND ${price.max}', {
    user: {name: 'John'},
    price: {min: 1, max: 5}
})
    .then(data => {
        // data[0] = users
        // data[1] = products
    })
    .catch(error => {
        
    });

它会和你的函数一样快,有两个光标,而且更简单。

【讨论】:

    【解决方案2】:
    db
    .tx(t => {
      return t.batch([
                t.func('get_data', [name, key, retCursor1, retCursor2]),
                t.any('FETCH ALL IN $1', retCursor1),
                t.any('FETCH ALL IN $1', retCursor2)
            ]);
        })
    .then(data => {
      console.log('DATA:', data); 
    })
    .catch(error => {
      console.log('ERROR:', error); 
    });
    

    【讨论】:

    • 底层驱动node-postgres不支持FETCH查询。
    猜你喜欢
    • 1970-01-01
    • 2018-01-07
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 2021-07-19
    • 2021-08-09
    • 1970-01-01
    相关资源
    最近更新 更多