简体   繁体   中英

How to make a nested queries on mysql with Node.js?

I'm trying to make a nested queries with mysql on Node.js with Express, the result should be a json with three nested, the problem is that the return doesn't show me the third nested, my code is:

app.get('/devices/:id', ensureToken, function(req, res){    
    jwt.verify(req.token, jwt_secret, function(err, data) {
        if (err) {
          res.sendStatus(403);
        } else {
            var segment_id = req.param('id');

        //Select devices for segment        
        var ls_devices = 'SELECT d.device_id AS id, d.device_name AS name, d.device_serial AS serial, d.device_description AS description, d.device_key AS keyatom, d.device_type AS type_id, dt.device_type_name AS type, d.device_user_id AS user_id, u.user_name AS username, d.device_segment_id AS segment_id, sg.segment_name, d.device_public AS isPublic, d.device_status AS status FROM ((g_devices d LEFT JOIN g_user u ON u.user_id = d.device_user_id) LEFT JOIN g_device_type dt ON dt.device_type_id = d.device_type) LEFT JOIN g_segments sg ON sg.segment_id = d.device_segment_id WHERE d.device_status = 1 AND sg.segment_id = '+segment_id;
        connection.query(ls_devices, function (error, results, fields) {
                  if (error) throw error;
                  if(results.length != 0) {                                                     
                      var j = JSON.parse(JSON.stringify(results));
                      var i = 0;
                      var d = [];
                    j.forEach(function(r,index_r){                        
                          //
                          var ls_controllers = 'SELECT c.device_controller_id AS id, c.device_controller_name AS name, c.device_controller_description AS description, c.device_controller_devcon_type AS type_id, ct.devcon_name AS type, ct.devcon_description AS description, d.device_name AS device, d.device_id AS device_id, d.device_serial AS serial, c.device_controller_public AS public, c.device_controller_date_register AS registered, c.device_controller_date AS date, c.device_controller_status AS status  FROM (g_device_controller c LEFT JOIN g_device_controller_type ct ON ct.devcon_id = c.device_controller_devcon_type) LEFT JOIN g_devices d ON d.device_id = c.device_controller_device_id WHERE c.device_controller_status = 1 AND d.device_id = '+r.id;
                          connection.query(ls_controllers, function (error_c, results_c, fields_c) {                            
                            var k = JSON.parse(JSON.stringify(results_c));
                            d.push({device:r.name,controller:[]})
                            k.forEach(function(r2,index_r2){                                                                        
                                d[index_r].controller.push({name:r2.name,action:[]})
                                var ls_actions = 'SELECT a.action_id AS id, a.action_name AS name, a.action_description AS description, a.action_type AS type_id, aty.action_type_name, aty.action_type_description AS type_description, a.action_controller_device_id AS device_id, a.action_control AS control, a.action_value AS value, a.action_time AS time, a.action_times AS times, a.action_date AS date, a.action_status AS status  FROM g_actions a LEFT JOIN g_action_type aty ON aty.action_type_id = a.action_type WHERE a.action_controller_id = '+r2.id;
                                  connection.query(ls_actions, function (error_a, results_a, fields_a) {                                    
                                    if(results_a.length > 0) {
                                        var l = JSON.parse(JSON.stringify(results_a));
                                        l.forEach(function(r3, index_r3){                                                                                                               
                                            d[index_r].controller[index_r2].action.push({id_a:r3.id,name_a:r3.name});                                           
                                            console.log(JSON.stringify(d))
                                        });                                     
                                    }                                   
                                });
                            });                                           
                            i ++;                           
                            if(i == j.length)
                            {                               
                                return res.json(d); 
                            }                           
                          });                         
                    })
                }
              else {
                return res.json({devices:false});   
              }         
            }); 
    }
    });     
});

My web response is:

[
    {
        "device": "device one",
        "controller": [
            {
                "name": "device controller One",
                "action": []
            }
        ]
    },
    {
        "device": "device two",
        "controller": []
    }
]

And the print of the last array push is:

[ { "device": "device one", "controller": [ { "name": "device controller One", "action": [ { "id_a": 1, "name_a": "device action One" } ] } ] }, { "device": "device two", "controller": [

]

} ]

k.forEach() does not wait for connection.query() to finish, so effectively the queries are skipped. The remedy is to do something similar to what you did with j.forEach() , but i++ should not happen until all of those finish too.

(Other notes: you could use promises , or async/await and make the flow appear much more neatly, or if you want to stick with learning callbacks you could use async library to simplify some of this)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM