Javascript 使用Nodejs在Mysql中插入多个值并用响应通知用户
我正在创建一个新的Web服务,其中我发送一个带有JSON的curl命令,JSON包含一个数组,如下所示Javascript 使用Nodejs在Mysql中插入多个值并用响应通知用户,javascript,mysql,node.js,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现在被插入,在数据库中它有c
[{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和tempid3一样
但是,当我试图向客户机显示更新的值时,它只显示一个值,最后一次更改,而不是整个更新的数组。这是因为connection.query函数的异步性质,所以我需要这方面的帮助,这是我的Web服务
联系人添加Web服务-->
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);
}
});
}
}
//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");
}
});
}
for(var i=0;i
//ContactSync为数据库添加联系人模块
exports.addcontact=函数(arr、电子邮件、addnum、回调)
{
var计数器=0;
变量uid;
var data=新数组();
var showinsert=新数组();
var值=新数组();
var datatable=新数组();
插入变量=新数组();
var-tempid=0;
connection.query('SELECT UID FROM user where email1=“”+email.email+””,函数(err、行、字段){
如果(错误)
{
犯错误;
}
其他的
{
如果(行[0]!=未定义)
{
uid=行[0]['uid'];
}
其他的
{
uid=“数据库中没有id”;
}
}
});//获取插入用户的UID
//生成用户提供数据的数组
对于(var j=0;j我不确定具体的问题是什么,但您共享的代码中存在一些问题,这些问题迟早会困扰您。其中之一可能会导致您的问题
比赛条件
如果查询SELECT UID FROM user where email1=
出于任何原因所花费的时间超过SELECT column\u name FROM information\u schema。columns
就在它的下方,那么变量uuid
将没有值,逻辑将失败。请记住,这些调用是非阻塞的,因此不能依赖于一个变量在另一个之前,除非它们是嵌套的或使用另一个流控制机制(正如@Tracker指出的,这种机制很流行)
捕捉边缘案例
在下一行中,您将为uid
变量指定一个字符串值,然后继续使用该变量,即使它现在包含错误消息
uid="no id in database";
这样做意味着您的代码以后将无法做出反应。请使用不同的变量,保留uid=undefined
,或者立即返回带有错误的回调,例如
return callback(new Error("user not found"));
报告错误
除非您想终止进程,否则不要在节点中抛出错误,例如服务器启动期间的依赖性问题。它不像Java那样工作,异步错误不会被try/catch捕获,并且会终止进程或使您处于难以解释的状态。相反,将error对象作为回调的第一个参数,并将其返回immed最近,像这样:
if ( err ) return callback(err);
connection.query('SELECT UID FROM user where email1=?', [email.email], ...
然后,在客户端代码中,您可以始终检查第一个参数,以查看是否存在问题
安全问题
正如@Tracker所提到的,永远不要这样做:
connection.query('SELECT UID FROM user where email1="'+email.email+'"', ...
如果变量的值以“drop table user;”
或类似形式传递,则您会遇到麻烦。相反,您可以使用节点mysql的内置转义,如下所示:
if ( err ) return callback(err);
connection.query('SELECT UID FROM user where email1=?', [email.email], ...
白名单
您正在查询信息\u架构。列
以检测哪些字段是有效的,然后将它们插入用户联系人
。这是一个聪明的技巧,但将3个查询过程增加到4个查询,并会问到是否有用户不应在其中插入数据的字段。使用列白名单可能看起来很简单ike需要维护更多的代码,但实际上比动态匹配列所需的所有代码都要简单
阵列
我没有看到函数inArray()
的源代码,但它看起来与Array.prototype.indexOf()
的功能相同,因此使用它可能更好
if ( datatable.indexOf(data[k]) > -1 ) inserting.push(data[k]);
您可以删除的每一行自定义代码都是一行您不必维护的代码。有三个争议点…首先,建议将您的检查/插入包装到一个SQL语句中,该语句返回与电子邮件地址匹配的给定用户的现有uid或新uid…第二,建议参数化查询,而不是字符串连接…第三,查看npm install async--save
async模块将提供对集合进行迭代的方法,并返回完整的结果集或错误。第四,您应该在整个过程中使用事务,以便它可以作为一个整体成功或失败。您好,感谢您的评论,我已经粘贴了我的new更新了服务端的代码,我正在运行foreach,但变量ardata在响应时仍然为空/无,请帮助假设ardata是数组[]
尝试ardata.push(值)ardata是一个简单的变量,我已经尝试过了,事实上我刚刚使用了Async.Seriesh这里是当前的代码-->非常感谢您宝贵的时间和宝贵的教训,从现在起我将永远记住这一点。再次感谢。我再次从头做起,这次我使用了查询嵌套,这是一个不好的做法吗?嵌套很好,但可以我的建议是先使用嵌套,直到你对这种类型的代码感到满意,然后再研究async
。我个人并不喜欢承诺,但这也是一种选择。另外一个建议是,如果你给匿名函数起一个名字,例如doSomething(函数myUniquelyNamedCallback(){…})
,则名称将显示在堆栈跟踪中,而不是“匿名函数”。另一个提示…使用节点检查器向重要点添加断点,您将能够一步一步地浏览应用程序,同时查看变量的值