我是Node的新手,在从Oracle中读取时遇到问题。
我已经设置了所有基本示例,可以发出基本查询,并处理结果等。
我遇到的问题是我需要;
执行一个查询(Q1)
对于Q1结果中的每个项目,我需要执行第二个查询(Q2)
我需要将Q1和Q2s的结果合并到一个数组中以作为一个承诺返回
我正在努力寻找一个可以执行#2的示例-使用与Q1相同的连接,对从Q1返回的每个项目多次调用相同的查询。
我的代码如下-我首先执行读取操作,然后遍历存储connection.execute对象的结果,然后再通过Promise.all行运行该对象-在我编写代码之前,要输出该结果以使其正常工作逻辑将Q1和Q2的结果相结合。
当我通过mocha运行此命令时,的结果不包含任何数据-我看到列标题,但没有数据。
那我在这里想念什么?
// placeholder for the connection
let conn;
// return case list array
var caseList = [];
var queryList = [];
return new Promise((resolve, reject) => {
// retrieve connection
oracledb.getConnection({
user: dbconfig.user,
password: dbconfig.password,
connectString: dbconfig.connectString
}) // the connection is returned as a promise
.then(connection => {
console.log('Connected to the DB!');
// assign connection
conn = connection;
// execute statement
return connection.execute(
`select caseid, casereference, startdate from caseheader inner join orgobjectlink on caseheader.ownerorgobjectlinkid = orgobjectlink.orgobjectlinkid where orgobjectlink.username = :username`,
[params.username], {
outFormat: oracledb.OBJECT // set the output format to be object
}
);
})
.then(result => {
// iterate around rows
result.rows.forEach(row => {
var caseObj = {
caseID: row.CASEID,
reference: row.CASEREFERENCE,
dateAssigned: moment(row.STARTDATE).format('YYYY-MM-DD'),
username: params.username,
}
caseList.push(caseObj);
console.log(caseObj.caseID)
queryList.push(conn.execute(`select concernroleid, concernrolename from concernrole inner join caseparticipantrole on concernrole.concernroleid = caseparticipantrole.participantroleid where caseparticipantrole.caseid = :caseID and (caseparticipantrole.typecode = 'PRI' or caseparticipantrole.typecode = 'MEM')`,
[caseObj.caseID], {
outFormat: oracledb.OBJECT
}));
});
// build up queries
return Promise.all(queryList).then(results => {
console.log(results);
Promise.resolve(results);
}, err => {
console.log(err);
});
}).then({
if(conn){
console.log("Closing DB connection");
conn.close();
}
}).catch(err => {
console.log('Error', err);
});
});
最佳答案
一个问题是Promise.all().then...
函数不返回任何内容(并且不需要附加的resolve()
)。进行排序的方法是构建小的,可测试的,承诺返回的函数,并分别对其进行测试。
从简单开始,编写摩卡测试以连接到数据库...
function connect() {
return oracledb.getConnection({
user: dbconfig.user,
password: dbconfig.password,
connectString: dbconfig.connectString
});
}
这是可以在数据库上运行命令的命令。使用一个简单的查询对此进行测试,您知道它将返回一些结果。
function executeCmd(connection, cmd, params) {
return connection.execute(cmd, params, { outFormat: oracledb.OBJECT });
}
仅用这两个(还有一个),我们就可以概述一个简单的功能来完成这项工作:连接到数据库,运行选择,异步处理每个结果,然后断开连接。
function connectAndQuery(username) {
let connection;
return connect().then(result => {
connection = result;
let cmd = `select caseid, casereference, startdate from caseheader inner join orgobjectlink on caseheader.ownerorgobjectlinkid = orgobjectlink.orgobjectlinkid where orgobjectlink.username = :username`;
return executeCmd(connection, cmd, [username]);
}).then(result => {
let promises = result.rows.map(row => processCaseRow(connection, row, username));
return Promise.all(promises);
}).then(result => {
// result should be an array of caseObj's
return connection.close().then(() => result);
});
}
构建和测试的最后一件事是一个返回承诺的函数,该函数处理上面主要函数中的一行。
我不得不对此采取一些自由,但是我认为目标是-给定一个代表“案例”的行-建立一个案例对象,包括可与caseID查询的“ concernedRoles”的集合。 (最后一点是我的想法,但您可以根据需要构建一个单独的集合)
// return a promise that resolves to an object with the following properties...
// caseID, reference, dateAssigned, username, concernedRoles
// get concernedRoles by querying the db
function processCaseRow(connection, row, username) {
var caseObj = {
caseID: row.CASEID,
reference: row.CASEREFERENCE,
dateAssigned: moment(row.STARTDATE).format('YYYY-MM-DD'),
username: username
}
let cmd = `select concernroleid, concernrolename from concernrole inner join caseparticipantrole on concernrole.concernroleid = caseparticipantrole.participantroleid where caseparticipantrole.caseid = :caseID and (caseparticipantrole.typecode = 'PRI' or caseparticipantrole.typecode = 'MEM')`;
return executeCmd(connection, cmd, row.CASEID).then(result => {
caseObj.concernedRole = result
return caseObj
})
}