1

I need to fetch multiple cursors from pg functions in Nodejs.

I have tried both kinds of function writing methods in PG as said in below link: http://www.sqlines.com/postgresql/how-to/return_result_set_from_stored_procedure

In PG Admin||| query tool i can able to view the output for multiple cursors by giving the name of it. I want to fetch the same from node js application, I'm using "pg-promise".

Option-1

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

Option-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 will return 2 refCursors.

But No luck, can someone suggest what is the best way to fetch multiple cursor in Node js.

6
  • What you are passing into db.func as parameters can only be input parameters. That syntax does not support output parameters. Commented May 20, 2017 at 13:07
  • In option-2 First 2 elements are input, but refcursor1 & 2 are named cursors expecting output to be recorded in DB. Same kind i have tried from pg admin, i m getting result and query as below.. . 'select get_data( 'SFO', 'FRA' , 'result1', 'result2' ); FETCH all IN "result1"; FETCH all IN "result2";' Commented May 20, 2017 at 17:10
  • That cannot work directly with pg-promise, it requires a special approach with the use of a cursor. See also: stackoverflow.com/questions/12101773/… Commented May 20, 2017 at 17:25
  • Best is to redesign the function so you can use this approach: github.com/vitaly-t/pg-promise/wiki/… Commented May 20, 2017 at 17:26
  • 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 "<unnamed portal 1>"', function (err, r1) { }); db.query('FETCH ALL FROM "<unnamed portal 2>"', function (err, r2) { }); db.query("COMMIT;"); } Commented May 21, 2017 at 6:51

2 Answers 2

0

From the author of pg-promise.


Unfortunately, the underlying driver node-postgres does not support FETCH queries.

They recommend to use a separate module for it - node-pg-cursor, which I tried, but couldn't make it work for your case, see the issue I opened: https://github.com/brianc/node-pg-cursor/issues/34

My advise is to try and avoid it altogether, by not returning any cursors from functions, or at least the ones that you want to call directly from Node.js.

If you think in terms of performance and efficiency, then the best way is to execute your multiple SELECT queries in a single command via method multi, which was added in 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 => {
        
    });

It will be just as fast as your function with two cursors, and way simpler.

Sign up to request clarification or add additional context in comments.

Comments

-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); 
});

1 Comment

The underlying driver node-postgres does not support FETCH queries.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.