记录集对象的getrows方法未按顺序调用

时间:2018-10-08 19:45:44

标签: javascript node.js ecmascript-6 recordset

调用Oracle SP,它将数据填充到记录集中。

通过记录集getrows()方法获取行。

当调用getrows方法并传递用于获取内部方法的函数时,该方法始终在最后运行。

第一个方法调用内部方法,内部方法接收到数据,并将记录集发送到内部函数。

以下代码中的示例函数调用方法返回空数据,然后运行responseObj.push。之后,getrows方法处理。

function lookups(req, res, next) {
    rows = functioncall(context);
    responesObj.push({ "Return Data": rows });
}

function simpleProcedureExecute(query, bindvars, opts = {}) {
    return new Promise((resolve, reject) => {
    oracledb.getConnection(
        conn,

        function (err, connection) {
            if (err) throw err;
            connection.execute(
                query,
                bindvars,
                function (err, result) {
                    if (err) {
                        console.error(err.message);

                        reject(err);
                    }
                    procJson = [];
                    function processResultSet() {

                        console.log("internal method");
                        console.log(result.outBinds.result);
                        try {

                            result.outBinds.result.getRows(1000, function (err, rows) {

                                if (err) console.log(err);

                                if (rows.length) {
                                    for (var i = 0; i < rows.length; i++) {
                                        procJson.push({});
                                        for (var j = 0; j < result.outBinds.result.metaData.length; j++) {
                                            procJson[i][result.outBinds.result.metaData[j].name.toLowerCase()] = rows[i][j];
                                        }
                                    }


                                    processResultSet();
                                    return;

                                }
                                resultSet.close(function (err) {
                                    if (err) console.error(err.message);

                                    conn.release(function (err) {
                                        if (err) console.error(err.message);
                                    });
                                });
                            });

                        }
                        catch (err) {
                            console.log(err);
                        }


                    }
                    processResultSet();
                }

            );
        }
    );
    resolve(procJson);
});
}

2 个答案:

答案 0 :(得分:0)

最明显的问题是您兑现承诺的时间-太早了。您是在resolve通话之外调用oracledb.getConnection。您尚未建立连接,尚未执行查询,也尚未收集行。您必须先完成所有这些操作,然后调用resolve并传递数据。

当您不熟悉Node.js时,这是您难以解决的事情之一。观看此视频,可能会有所帮助:https://www.youtube.com/watch?v=iAdeljxq_hs&t=0s&index=2&list=PL_lVOJzXeE__1Kh3ko0F-39-cpNLPXbJL

此外,请参阅本系列,其中涵盖了Node.js中的不同异步模式。大多数Node.js开发人员从回调开始,然后转向用于异步工作的替代模式:https://jsao.io/2017/06/how-to-get-use-and-close-a-db-connection-using-various-async-patterns/

最后,这是一个如何使用async / await迭代结果集的示例:

const oracledb = require('oracledb');
const config = require('./dbConfig.js');

async function runTest() {
  let conn;
  let result;

  try {
    conn = await oracledb.getConnection(config);

    result = await conn.execute(
      'select * from all_objects where rownum < 100',
      [],
      {
        resultSet: true
      }
    );

    let row;

    while (row = await result.resultSet.getRow()) {
      console.log(row);
    }
  } catch (err) {
    console.error(err);
  } finally {
    if (result && result.resultSet) {
      try {
        await result.resultSet.close();
      } catch (err) {
        console.error(err);
      }
    }

    if (conn) {
      try {
        await conn.close();
      } catch (err) {
        console.error(err);
      }
    }
  }
}

runTest();

根据工作量,最好使用getRows一次获取更多行:

const oracledb = require('oracledb');
const config = require('./dbConfig.js');

async function runTest() {
  let conn;
  let result;

  try {
    conn = await oracledb.getConnection(config);

    result = await conn.execute(
      'select * from all_objects where rownum < 100',
      [],
      {
        resultSet: true
      }
    );

    let rows = await result.resultSet.getRows(50);

    while (rows.length) {
      for (let x = 0; x < rows.length; x += 1) {
        console.log(rows[x]);
      }

      rows = await result.resultSet.getRows(50);
    }
  } catch (err) {
    console.error(err);
  } finally {
    if (result && result.resultSet) {
      try {
        await result.resultSet.close();
      } catch (err) {
        console.error(err);
      }
    }

    if (conn) {
      try {
        await conn.close();
      } catch (err) {
        console.error(err);
      }
    }
  }
}

runTest();

答案 1 :(得分:0)

从Dan那里获得指示后,无需调用内部函数即可直接使用getrows。在下面找到我的代码以解决该问题。

async function simpleProcedureExecute(query, bindvars, opts = {}) {
let rowss;
let conn;
let procJson = [];
try {
    conn = await oracledb.getConnection();
    result = await conn.execute(query, bindvars);
    rowss = await result.outBinds.result.getRows(1000);
    if (rowss.length) {
        for (var i = 0; i < rowss.length; i++) {
            procJson.push({});
            for (var j = 0; j < result.outBinds.result.metaData.length; j++) {
                procJson[i][result.outBinds.result.metaData[j].name.toUpperCase()] = rowss[i][j];
            }
        }
    }
    return procJson;
} catch (err) {
    console.log(err);
} finally {
    if (conn) { // conn assignment worked, need to close
        try {
            await conn.close();
        } catch (err) {
            console.log(err);
        }
    }
}
}