调用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);
});
}
答案 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);
}
}
}
}