1. 程式人生 > 資料庫 >mysql從一張表查詢批量資料並插入到另一表中的完整例項

mysql從一張表查詢批量資料並插入到另一表中的完整例項

說在前面

nodejs 讀取資料庫是一個非同步操作,所以在資料庫還未讀取到資料之前,就會繼續往下執行程式碼。
最近寫東西時,需要對資料庫進行批量資料的查詢後,insert到另一表中。
說到批量操作,讓人最容易想到的是for迴圈。

錯誤的 for 迴圈版本

先放出程式碼,提前說明一下,在這裡封裝了sql操作:sql.sever(資料庫連線池,sql語句拼接函式,回撥函式)

for(let i=0;i<views.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','後臺','產品'];	//這裡是郵件相關程式碼
  let group = allGroup[selfgroup - 1];
  let mailmsg = "您好," + group + "組通過人員表已提交,請您儘快稽核!";
  mail.mailepass(mailmsg);
  res.write(JSON.stringify({
   style:1,msg:"已將名單提交,待管理員稽核!"
  }));
  res.end();
  })
 })
}

上面程式碼中,是先進行資料查詢再進行資料的插入,(在這裡假定有2條資料)按照常理,我們想的執行順序是:查詢 插入 查詢 插入。然而,並非我們所想那麼簡單,雖然插入操作也確實在資料庫查詢的回撥中寫的,但是實際的順序是:查詢 查詢,一旦直接進行了兩次查詢,想當然後面的程式碼直接報錯了。沒來得及回撥時,已經執行了第二次迴圈。

改進的 for 迴圈版本

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,time) SELECT xuehao,NOW() FROM registryinformation WHERE xuehao=' + sql.escape(views.xuehao[i]) + ' and pass=' + state,function () {
  if (i == views.xuehao.length - 1) {
   let allGroup = ['Android','產品'];
   let group = allGroup[selfgroup - 1];
   let mailmsg = "您好," + group + "組通過人員表已提交,請您儘快稽核!";
   mail.mailepass(mailmsg);
   res.write(JSON.stringify({
    style: 1,msg: "已將名單提交,待管理員稽核!"
   }));
   res.end();
  }
 })
} 

這樣,資料庫操作正確,目的達到了。但是仔細想來,這樣做還是有缺陷的。如果資料量小還好說,但若資料量大時,這樣導致程式和資料庫建立多次連線,會增加伺服器負荷。

改進版

結合上一次的缺陷,顧名思義,這次我們要減少程式與資料庫連線次數。於是,我們不再將插入和查詢寫到一起,而是將其分開,進行批量的插詢,從而利用所查資料批量插入。程式碼如下:

let sqlString = 'SELECT xuehao,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,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','產品'];
 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([列值],[列值])),([列值],[列值]));

總結

到此這篇關於mysql從一張表查詢批量資料並插入到另一表中的文章就介紹到這了,更多相關mysql查詢批量資料插入到另一表內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!