使用Nodejs在Mysql中插入多个值并通知用户响应

时间:2013-11-19 20:51:56

标签: javascript mysql node.js

我正在创建一个新的web服务,我发送一个带有JSON的curl命令,而JSON包含一个数组

[{tempid:1,email:abc@123,address:asd},{tempid:2,email:abc@12345,address:asd45},{tempid:3,email:abc@1234,address:asd4}]

现在当我传递并在mysql表中插入数组时,tempid只是为了向用户显示在数据库中生成的联系人ID的映射为tempid:1现在已插入,而在数据库中它有cid 120,就像这样对于tempid2和3,

但是当我试图向客户端显示更新的值时,它只显示一个值,最后一次更改不是整个更新的数组。因为connection.querry函数的异步性质,所以我需要帮助,这里是我的webservice

contactadd webservice - >

for(var i=0;i<=request.body.contact.length-1;i++)
            {
             if(request.body.contact[i].tempid)
                { var ardata=new Array();
                    var o=request.body.contact[i];
                    pair=Object.keys(o).map(function(a){ return [a, o[a]] });
                    AM.addcontact(pair,request.session.user,request.body.contact.length,function(e,o){
                        if(!o)
                        {
                             response.send('something went wrong'+e);

                        }
                        else
                        {
                           //response.send(o);
                        }

                    });


                }
    }

以下是database.js脚本中的更新功能 - &gt;

//ContactSync-addcontact module for database 
exports.addcontact=function (arr,email,addnum,callback)
{ 
  var counter=0;
  var uid;
  var data=new Array();
  var showinsert=new Array();
  var values=new Array();
  var datatable=new Array();
  var inserting=new Array();

  var tempid=0;
   connection.query('SELECT UID FROM user where email1="'+email.email+'"',function(err,rows,fields){
    if(err)
    {
     throw err;
    }
    else
    {
    if(rows[0]!=undefined)
    {
     uid=rows[0]['UID'];
    }
    else
    {
    uid="no id in database";
    }
    }
    });// get the UID of the inserting user

    // make array of user provided data
    for(var j=0;j<=arr.length-1;j++)
    {
     if(arr[j][0]!='tempid')
     {
      data.push(arr[j][0]);
     }
     else
     {
      tempid=arr[j][1];
     }
    }

    connection.query('SELECT column_name FROM information_schema.columns where table_schema="webservice" AND table_name="usercontacts"',function(err,rows,fields){
    if(err)
    {
     throw err;
    }
    else
    {

    for(var i=0;i<=rows.length-1;i++)
    {
      datatable.push(rows[i]['column_name']);

    }
    }
       for(var k=0;k<=datatable.length-1;k++)
        {
          if(inArray(data[k],datatable))
          {
            inserting.push(data[k]);
          }
        }
        if(inserting.length>0)
        {


            for(var z=0;z<=arr.length-1;z++)
            {
              if(inArray(arr[z][0],inserting))
               { 

                 values.push('"'+arr[z][1]+'"');

               }
            }


            // Insert tempid values and data in the usercontacts table with inserting and values

            connection.query('INSERT INTO usercontacts (cid,uid,'+inserting+') VALUES("","'+uid+'",'+values+')',function(err,rows,fields){
            if(err)
            {
            throw err;
            }
            else
            {  
                connection.query('SELECT * FROM usercontacts WHERE uid="'+uid+'" ORDER BY cid DESC LIMIT 0,'+addnum+'',function(err,rows,fields){
                if(err)
                {
                    throw err;
                }
                else

                {   showinsert.push('temp-id: '+tempid+',cid:'+rows[0].cid+',uid:'+uid);
                    //for(var i=0;i<=inserting.length-1;i++)
                    forEach(inserting,function(row,index)
                    {
                      showinsert.push(inserting[index]+":"+values[index]);
                      counter+=1;
                    });

                    callback(null,showinsert);

                }

                });
            }

            });

            //insertion finished 


        }
        else
        {
          callback("Please Provide atleast one field to enter with tempid");
        }

  });


}

我只需要在已经插入的数组中插入所有回调并向用户显示该数组,请帮助,完全卡住然后只有我正在尝试StackOverflow。

感谢您阅读BTW

结束

1 个答案:

答案 0 :(得分:1)

我不确定具体问题是什么,但是您共享的代码存在一些问题,迟早会让您感到困惑。其中一个可能会导致您的问题。

竞争条件

如果查询SELECT UID FROM user where email1=由于任何原因需要的时间超过其下方的SELECT column_name FROM information_schema.columns那么您将没有变量uuid的值,并且您的逻辑将失败。请记住,这些调用是非阻塞的,因此除非它们嵌套或使用其他流控制机制,否则不能依赖于另一个之前的完成(如@Tracker指出的那样,async很受欢迎)。

抓住边缘案例

在下面的行中,您将字符串值分配给uid变量,然后继续使用该变量,即使它现在包含错误消息。

    uid="no id in database";

这样做意味着稍后您的代码将无法做出反应。而是使用不同的变量,离开uid = undefined或立即返回带有错误的回调,例如

    return callback(new Error("user not found"));

举报错误

除非您想要终止进程,否则不要在Node中抛出错误,例如服务器启动期间的依赖问题它不像Java一样工作,异步错误不会被try / catch捕获,并且会导致您的进程被终止或让您处于难以理解的状态。而是将错误对象作为回调的第一个参数并立即返回,如下所示:

    if ( err ) return callback(err);

然后在您的客户端代码中,您始终可以检查第一个参数以查看是否存在问题。

安全问题

正如@Tracker所提到的,不要这样做

    connection.query('SELECT UID FROM user where email1="'+email.email+'"', ...

如果变量的值以"; drop table user;或类似方式传递,那么您就遇到了麻烦。相反,您可以像这样使用node-mysql的构建转义:

    connection.query('SELECT UID FROM user where email1=?', [email.email], ...

<强>白名单

您正在查询information_schema.columns,以便检测哪些字段有效,然后将其插入usercontacts。这是一个聪明的技巧,但是将3个查询过程增加到4个查询,如果有任何字段不允许用户插入数据,则会引发问题。使用列白名单可能看起来要维护更多代码,但实际上比动态匹配列所需的所有代码更简单。

<强>阵列

我没有看到函数inArray()的来源,但看起来它与Array.prototype.indexOf()的作用相同,所以最好使用它。 e.g。

    if ( datatable.indexOf(data[k]) > -1 ) inserting.push(data[k]);

您可以删除的每行自定义代码都是您不必维护的一行代码。