记录集对象的 getrows 方法未按顺序调用
getrows method of the recordset object does not call in sequence
正在调用向记录集中填充数据的Oracle SP
通过记录集 getrows()
方法获取行。
当调用 getrows
方法并传递一个用于获取内部方法的函数时,最后总是 运行。
第一个方法调用了内部方法,内部方法接收到数据,记录集正在发送到内部函数。
下面代码中的示例函数调用方法 return 清空数据,然后 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);
});
}
最明显的问题是您解决承诺的时间 - 这太早了。您在调用 oracledb.getConnection
之外调用 resolve
。您还没有连接,还没有执行查询,还没有收集行。您必须先完成所有这些,然后调用 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();
在从 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);
}
}
}
}
正在调用向记录集中填充数据的Oracle SP
通过记录集 getrows()
方法获取行。
当调用 getrows
方法并传递一个用于获取内部方法的函数时,最后总是 运行。
第一个方法调用了内部方法,内部方法接收到数据,记录集正在发送到内部函数。
下面代码中的示例函数调用方法 return 清空数据,然后 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);
});
}
最明显的问题是您解决承诺的时间 - 这太早了。您在调用 oracledb.getConnection
之外调用 resolve
。您还没有连接,还没有执行查询,还没有收集行。您必须先完成所有这些,然后调用 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();
在从 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);
}
}
}
}