从postgres db获取节点js中的多个Refcursor(使用pg-promise)

时间:2017-05-20 10:24:22

标签: javascript node.js postgresql pg-promise

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

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

在PG Admin |||中查询工具我可以通过给出它的名称来查看多个游标的输出。  我想从节点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 Fucntion将返回2个refCursors。

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

2 个答案:

答案 0 :(得分:0)

来自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 => {

    });

它将与使用两个游标的函数一样快,并且更简单。

答案 1 :(得分:-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); 
});