Метод getrows объекта набора записей не вызывается последовательно - PullRequest
0 голосов
/ 08 октября 2018

Вызов Oracle SP, который заполняет данные в наборе записей.

Выборка строк с помощью метода набора записей getrows().

Когда вызывается метод getrows и передается функция для извлечениявнутренние методы всегда выполняются в конце.

Первый метод вызывает внутренний метод, и внутренний метод получает данные, и набор записей отправляется внутренней функции.

Пример в приведенном ниже кодеМетод functioncall возвращает пустые данные и затем 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 голосов
/ 11 октября 2018

После получения указания от Дэна использовать 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);
        }
    }
}
}
0 голосов
/ 09 октября 2018

Самая очевидная проблема - это время, когда вы выполняете обещание, которое слишком рано.Вы вызываете resolve вне вызова на oracledb.getConnection.У вас еще нет соединения, вы еще не выполнили запрос и еще не собрали строки.Сначала вы должны сделать все это, а затем вызвать resolve и передать данные.

Это одна из самых сложных вещей, когда вы начинаете работать с 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();
...