說在前面
nodejs 讀取數(shù)據(jù)庫是一個異步操作,所以在數(shù)據(jù)庫還未讀取到數(shù)據(jù)之前,就會繼續(xù)往下執(zhí)行代碼。
最近寫東西時,需要對數(shù)據(jù)庫進行批量數(shù)據(jù)的查詢后,insert到另一表中。
說到批量操作,讓人最容易想到的是for循環(huán)。
錯誤的 for 循環(huán)版本
先放出代碼,提前說明一下,在這里封裝了sql操作:sql.sever(數(shù)據(jù)庫連接池,sql語句拼接函數(shù),回調(diào)函數(shù))
for(let i=0;iviews.xuehao.length;i++){
sql.sever(pool,sql.select(["name"],"registryinformation",["xuehao="+sql.escape(views.xuehao[i])]),function(data){
sql.sever(pool,sql.insert("personnelqueue",["xuehao","name","selfgroup","time"],[sql.escape(views.xuehao[i]),data[0].name,selfgroup,'NOW()'],true),function(){
let allGroup = ['Android', 'ios', 'Web', '后臺','產(chǎn)品']; //這里是郵件相關(guān)代碼
let group = allGroup[selfgroup - 1];
let mailmsg = "您好," + group + "組通過人員表已提交,請您盡快審核!";
mail.mailepass(mailmsg);
res.write(JSON.stringify({
style:1,
msg:"已將名單提交,待管理員審核!"
}));
res.end();
})
})
}
上面代碼中,是先進行數(shù)據(jù)查詢再進行數(shù)據(jù)的插入,(在這里假定有2條數(shù)據(jù))按照常理,我們想的執(zhí)行順序是:查詢 插入 查詢 插入。然而,并非我們所想那么簡單,雖然插入操作也確實在數(shù)據(jù)庫查詢的回調(diào)中寫的,但是實際的順序是:查詢 查詢,一旦直接進行了兩次查詢,想當然后面的代碼直接報錯了。沒來得及回調(diào)時,已經(jīng)執(zhí)行了第二次循環(huán)。
改進的 for 循環(huán)版本
mysql 用一條語句可以完成查詢并插入,格式為:INSERT IGNORE INTO 插入表表名 (item1,item2) SELECT item1,item2 FROM 查詢表表名 WHERE,于是乎,便想到了下面的解決方案。
for (let i = 0; i views.xuehao.length; i++) {
sql.sever(pool, 'INSERT IGNORE INTO personnelqueue (xuehao,name,selfgroup,time) SELECT xuehao,name,selfgroup,NOW() FROM registryinformation WHERE xuehao=' + sql.escape(views.xuehao[i]) + ' and pass=' + state, function () {
if (i == views.xuehao.length - 1) {
let allGroup = ['Android', 'ios', 'Web', '后臺', '產(chǎn)品'];
let group = allGroup[selfgroup - 1];
let mailmsg = "您好," + group + "組通過人員表已提交,請您盡快審核!";
mail.mailepass(mailmsg);
res.write(JSON.stringify({
style: 1,
msg: "已將名單提交,待管理員審核!"
}));
res.end();
}
})
}
這樣,數(shù)據(jù)庫操作正確,目的達到了。但是仔細想來,這樣做還是有缺陷的。如果數(shù)據(jù)量小還好說,但若數(shù)據(jù)量大時,這樣導致程序和數(shù)據(jù)庫建立多次連接,會增加服務(wù)器負荷。
改進版
結(jié)合上一次的缺陷,顧名思義,這次我們要減少程序與數(shù)據(jù)庫連接次數(shù)。于是,我們不再將插入和查詢寫到一起,而是將其分開,進行批量的插詢,從而利用所查數(shù)據(jù)批量插入。代碼如下:
let sqlString = 'SELECT xuehao,name,selfgroup FROM registryinformation WHERE pass=' + state + ' AND (xuehao=' + sql.escape(views.xuehao[0]);
for (let i = 1; i views.xuehao.length; i++) {
sqlString += ' OR xuehao=' + sql.escape(views.xuehao[i]);
}
sqlString = sqlString + ')';
sql.sever(pool, sqlString, function (data) {
//拼接插入sql語句
let istSqlStr = 'INSERT IGNORE INTO personnelqueue (xuehao,name,selfgroup,time) VALUES (' + data[0].xuehao + ',' + sql.escape(data[0].name) + ',' + data[0].selfgroup + ',NOW())';
for (let j = 1; j data.length; j++) {
istSqlStr += ',(' + data[j].xuehao + ',' + sql.escape(data[j].name) + ',' + data[j].selfgroup + ',' + 'NOW())';
}
sql.sever(pool, istSqlStr, function () {
let allGroup = ['Android', 'ios', 'Web', '后臺', '產(chǎn)品'];
let group = allGroup[selfgroup - 1];
let mailmsg = "您好," + group + "組通過人員表已提交,請您盡快審核!";
mail.mailepass(mailmsg);
res.write(JSON.stringify({
style: 1,
msg: "已將名單提交,待管理員審核!"
}));
res.end();
})
})
補充
批量查詢語法(在這里and與or進行了混用) SELECT 列名,列名 FROM 表名 WHERE 條件 AND (item1=‘xxx' OR item1=‘yyy');
一條語句進行批量插入語法 INSERT INTO [ 表名 ]([ 列名] ,[ 列名 ]) VALUES([列值],[列值])),([列值],[列值])),([列值],[列值]));
總結(jié)
到此這篇關(guān)于mysql從一張表查詢批量數(shù)據(jù)并插入到另一表中的文章就介紹到這了,更多相關(guān)mysql查詢批量數(shù)據(jù)插入到另一表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- 一篇文章弄懂MySQL查詢語句的執(zhí)行過程
- 詳解MySQL 查詢語句的執(zhí)行過程
- Python使用sql語句對mysql數(shù)據(jù)庫多條件模糊查詢的思路詳解
- mysql查詢的控制語句圖文詳解
- Mysql將查詢結(jié)果集轉(zhuǎn)換為JSON數(shù)據(jù)的實例代碼
- 使用Visual Studio Code連接MySql數(shù)據(jù)庫并進行查詢
- MySQL查詢優(yōu)化之查詢慢原因和解決技巧
- mysql聚合統(tǒng)計數(shù)據(jù)查詢緩慢的優(yōu)化方法
- MySQL多表查詢的具體實例
- 分析mysql中一條SQL查詢語句是如何執(zhí)行的