あるテーブルからバッチデータをクエリし、それを別のテーブルに挿入する MySQL の完全な例

あるテーブルからバッチデータをクエリし、それを別のテーブルに挿入する MySQL の完全な例

事前に言っておく

Nodejs はデータベースを非同期操作として読み取るため、データベースがデータを読み取る前にコードの実行が継続されます。
最近何かを書いていたとき、データベースに対してバッチ データをクエリし、それを別のテーブルに挿入する必要がありました。
バッチ操作に関しては、 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', 'Backend', 'Product']; //ここにメール関連のコードがあります let group = allGroup[selfgroup - 1];
  let mailmsg = "こんにちは、" + group + "グループ承認リストが送信されました。できるだけ早く確認してください!";
  mail.mailepass(mailmsg);
  res.write(JSON.stringify({
   スタイル:1,
   メッセージ:「リストは送信されており、管理者による確認を待っています。」
  }));
  res.end();
  })
 })
}

上記のコードでは、最初にデータ クエリが実行され、次にデータ挿入が実行されます (ここでは、データが 2 つあると想定しています)。常識的に考えると、必要な実行順序は、クエリ挿入、クエリ挿入です。しかし、それは私たちが考えるほど単純ではありません。挿入操作は確かにデータベース クエリのコールバックに記述されていますが、実際の順序はクエリ クエリです。2 つのクエリが直接実行されると、後続のコードでエラーが報告されます。コールバックが実行される前に、2 番目のループがすでに実行されています。

改良された for ループ バージョン

mysql は、クエリと挿入を 1 つのステートメントで完了できます。形式は、INSERT IGNORE INTO insert table テーブル名 (item1、item2) SELECT item1、item2 FROM query table テーブル名 WHERE です。そこで、次の解決策を考えました。

(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) {
   allGroup を ['Android', 'ios', 'Web', 'Backend', 'Product'] とします。
   グループをallGroup[自己グループ - 1]とします。
   let mailmsg = "こんにちは、" + group + "グループ承認リストが送信されました。できるだけ早く確認してください!";
   mail.mailepass(mailmsg);
   res.write(JSON.stringify({
    スタイル: 1,
    メッセージ: 「リストは送信されており、管理者による確認を待っています。」
   }));
   res.end();
  }
 })
} 

このようにして、データベースは正しく動作し、目的が達成されます。しかし、よく考えてみると、このアプローチにはまだ欠陥があります。データ量が少ない場合は問題ありませんが、データ量が多い場合は、プログラムがデータベースと複数の接続を確立することになり、サーバーの負荷が増加します。

改良版

前回の欠陥と合わせて、名前が示すように、今回はプログラムがデータベースに接続する回数を減らす必要があります。したがって、挿入とクエリを一緒に記述するのではなく、それらを分離してバッチ挿入とクエリを実行し、クエリされたデータをバッチ挿入に使用します。コードは次のとおりです。

let sqlString = 'SELECT xuehao,name,selfgroup FROM registryinformation WHERE pass=' + state + ' AND (xuehao=' + sql.escape(views.xuehao[0]);
(i = 1 とします; i < views.xuehao.length; i++) {
 sqlString += ' または xuehao=' + sql.escape(views.xuehao[i]);
}
sqlString = sqlString + ')';
sql.sever(プール、sqlString、関数(データ) {
 //SQL ステートメントの結合と挿入 let istSqlStr = 'INSERT IGNORE INTO personnelqueue (xuehao,name,selfgroup,time) VALUES (' + data[0].xuehao + ',' + sql.escape(data[0].name) + ',' + data[0].selfgroup + ',NOW())';
 (j = 1; j < data.length; j++) の場合 {
 istSqlStr += ',(' + data[j].xuehao + ',' + sql.escape(data[j].name) + ',' + data[j].selfgroup + ',' + 'NOW())';
 }
 sql.sever(プール、istSqlStr、関数() {
 allGroup を ['Android', 'ios', 'Web', 'Backend', 'Product'] とします。
 グループをallGroup[自己グループ - 1]とします。
 let mailmsg = "こんにちは、" + group + "グループ承認リストが送信されました。できるだけ早く確認してください!";
 mail.mailepass(mailmsg);
 res.write(JSON.stringify({
  スタイル: 1,
  メッセージ: 「リストは送信されており、管理者による確認を待っています。」
 }));
 res.end();
 })
})

補充する

バッチ クエリ構文 (and と or が混在) SELECT column name, column name FROM table name WHERE condition AND (item1='xxx' OR item1='yyy');
バッチ挿入構文の 1 つのステートメント INSERT INTO [テーブル名]([列名],[列名]) VALUES([列値],[列値])),([列値],[列値])),([列値],[列値]));

要約する

これで、MySQL で 1 つのテーブルから大量のデータをクエリし、それを別のテーブルに挿入する方法についての説明は終わりです。MySQL クエリで大量のデータを別のテーブルに挿入する関連コンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • データの挿入とクエリのためのMySQLコマンドとステートメントの詳細な説明
  • JDBC は MySql データベースのステップに接続し、クエリ、挿入、削除、更新などを実行します。
  • MySQL データの挿入とデータのクエリ

<<:  Dockerコンテナの接続と通信の実装

>>:  HTML テーブルタグチュートリアル (26): セルタグ

推薦する

Ubuntuサーバーの一般的なコマンドの概要

以下のコマンドのほとんどは、コンソール/ターミナル/シェルで入力する必要があります。 'su...

Linux に起動方法を追加する (サービス/スクリプト)

システムの起動時に読み込む必要がある設定ファイル/etc/profile、/root/.bash_p...

プレフィックスケースを削除する Nginx リバース プロキシ構成のチュートリアル

nginx をリバース プロキシとして使用する場合、リクエストをそのまま次のサービスに転送するだけで...

Nginx設定の原理と実装プロセスの詳細な説明https

Linuxユーティリティcertbotを使用してhttps証明書を生成するこのツールは Let&#...

初心者のためのウェブサイト構築入門 - ウェブサイト構築に必要な条件とツール

今日は、初心者の次のような質問に答えます。学ぶ勇気さえあれば、自分のウェブサイトを構築するのは簡単で...

CSS3はウェブサイトの製品表示効果図を実現します

この記事では、CSS3 を使用した Web サイトの商品表示の効果を紹介し、皆さんと共有します。詳細...

HTML+CSSを使用してマウスの動きを追跡する

ユーザーがプライバシーを意識するようになり、オンライン トラッキングに対する予防策を強化するにつれて...

効率をN倍に高めるVimクイックリファレンステーブル15個

昨年の前半から開発と娯楽のために Linux を使い始めましたが、今では Windows には戻れま...

Node.jsをゼロから学ぶ

目次URL モジュール1. 解析メソッド2. フォーマット方法3. 解決方法イベントモジュール(イベ...

MySQLでTEXT/BLOB型を使用する際の注意点を詳しく説明します

1. TEXTとBLOBの違いTEXT ファミリと BLOB ファミリの唯一の違いは、BLOB 型は...

docker compose デプロイメントにおけるマスタースレーブレプリケーションの実装

目次構成解析サービス構築ディレクトリ構造ファイルを作成インスタンス構成サービスを開始するテストRed...

リモートホスト上でスクリプトや命令を実行する Zabbix の詳細な説明

シナリオ要件1. zabbix_server Web インターフェースのスクリプト機能を使用すると、...

CSS の子要素の Z インデックスと親要素の兄弟ノードの階層問題を解決する

1. 問題の出現フラット リストを作成しました。リストの一部には、マウスをホバーすると表示されるポッ...

純粋な HTML タグにどれくらい精通していますか?

以下の HTML タグには、基本的に既存のタグがすべて含まれています。数分かけて 1 つずつ参照する...

MySQL では SQL ステートメントはどのように実行されますか?

目次1. MySQLアーキテクチャの分析1.1 コネクタ1.2 クエリキャッシュ1.3 アナライザー...