我是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
    })
}

07-24 18:03
查看更多