MySQLカーソルの使い方と機能の詳細な説明

MySQLカーソルの使い方と機能の詳細な説明

[mysqlカーソルの使い方と機能]

例:

現在、テーブル A、B、C の 3 つのテーブルがあります。A と B は 1 対多の関係にあり、B と C は 1 対多の関係にあります。ここで、テーブル B のテーブル A の主キーをテーブル C に格納する必要があります。
従来の考え方では、テーブル B をクエリし、次に更新ステートメントを使用してテーブル C を更新しますが、テーブル B には 2,000 件を超えるレコードが存在します。
2,000 回以上実行する必要がありますか?これは明らかに非現実的です。最終的に、ストアド プロシージャを記述し、ループを通じて C テーブルを更新する方法を見つけました。
ただし、ストアド プロシージャはカーソルの形式で記述されます。

【導入】

カーソルは、実際には、複数のデータ レコードを含む結果セットから一度に 1 つのレコードを抽出できるメカニズムです。

カーソルはポインターとして機能します。

カーソルは結果セット内のすべての行を走査できますが、一度にポイントできるのは 1 行だけです。

カーソルの機能は、クエリ データベースによって返されたレコードを走査して、対応する操作を実行することです。

【使用法】

1. カーソルを宣言します: カーソル名 CURSOR for table; を宣言します (ここでのテーブルは、クエリする任意のコレクションにすることができます)
2. 定義されたカーソルを開きます: open cursor name;
3. 次のデータ行を取得します: FETCH cursor name into testrangeid, versionid;
4. 実行するステートメント(追加、削除、変更、チェック):これは具体的な状況によって異なります。
5. カーソルを解放します: CLOSE カーソル名;

注意: MySQL ストアド プロシージャ内の各ステートメントは ; で終わる必要があり、使用される一時フィールドはカーソルを定義する前に宣言する必要があります。

【例】

- 
始める 
 
--変数を定義します。declare testrangeid BIGINT; 
versionid を BIGINT として宣言します。 
完了した int を宣言します。 
--カーソルを作成し、データを保存します。cur_test CURSORを宣言します。 
 tp_testrange から id を testrangeid として、version_id を versionid として選択します。 
--カーソル内のコンテンツが実行された後、doneを1に設定します 
 NOT FOUND SET done=1 の継続ハンドラーを宣言します。 
--カーソルを開きます。open cur_test; 
--ループを実行 posLoop:LOOP 
--ループを終了するかどうかを判断します IF done=1 THEN 
  POSループを終了します。 
 終了の場合; 
--カーソル内の値を取得します FETCH cur_test into testrangeid,versionid; 
--更新操作を実行します。update tp_data_execute set version_id=versionid where testrange_id = testrangeid; 
 ループ終了 posLoop; 
--カーソルを解放します CLOSE cur_test; 
 
終わり 
-

例2:

ここで、ストアド プロシージャを使用して、iPhone の総在庫数をカウントし、その合計数をコンソールに出力する関数を作成します。

--Windows システムでストアド プロシージャを作成するときに、変数を宣言するために declaration を使用する必要がある場合は、このキーワードを追加する必要があります。そうしないと、エラーが報告されます。 
区切り文字 // 
StatisticStore が存在する場合は手順を削除します。 
CREATE PROCEDURE StatisticStore() 
始める 
 --カーソル データを受け取る変数を作成します。declare c int; 
 n varchar(20)を宣言します。 
 --total 変数を作成します。declare total int default 0; 
 --終了フラグ変数を作成します。declare done int default false; 
 --カーソルを作成します。declare cur cursor for select name,count from store where name = 'iphone'; 
 --カーソル ループの終了時の戻り値を指定します。declare continue HANDLER for not found set done = true; 
 --初期値を設定します。set total = 0; 
 --カーソルを開きます open cur; 
 --カーソル内のデータのループを開始します read_loop:loop 
 --カーソルが現在指しているデータに従って、cur を n,c にフェッチします。 
 --カーソルループが終了したかどうかを判断します。終了した場合は 
  leave read_loop; --カーソルループから抜け出す end if; 
 --データを取得するときに、カウント値を追加します。ここでは何でも好きなようにできます。 
 合計を合計 + c に設定します。 
 --カーソル ループを終了します。end loop; 
 --カーソルを閉じます close cur; 
 
 --出力結果 select total; 
終わり; 
-- ストアド プロシージャ call StatisticStore() を呼び出します。

フェッチは、カーソルが現在指しているデータ行を取得し、ポインタを次の行に向けることです。カーソルがすでに最後の行を指している状態で実行を続けると、カーソルがオーバーフローします。
ループ カーソルを使用する場合、最後のデータに到達したかどうかは監視されません。次のコードは無限ループを引き起こします。

read_loop:ループ 
cur を n,c にフェッチします。 
合計を total+c に設定します。 
ループを終了します。

MySql では、カーソル オーバーフローが発生すると、MySQL の定義済み NOT FOUND エラーがトリガーされます。したがって、上記の次のコードは、not found エラーがトリガーされたときに continue イベントを定義し、このイベントが発生したときに done 変数の値が変更されることを指定するために使用されます。

見つからない場合の続行ハンドラーを宣言し、done = true を設定します。

そこで、ループに次のコードを追加しました。

--カーソルループが終了したかどうかを判断します。終了した場合は 
 leave read_loop; --カーソルループから抜け出す end if;

done の値が true の場合、ループは終了します。次のコードを実行し続けます

使い方

カーソルを使用する方法は 3 つあります。
最初のものは、ループを使用した上記の実装です。
2 番目の方法は、while ループを使用する方法です。

StatisticStore1 が存在する場合はプロシージャを削除します。 
プロシージャ StatisticStore1() を作成します。 
始める 
 c int を宣言します。 
 n varchar(20)を宣言します。 
 合計 int のデフォルトを 0 と宣言します。 
 宣言完了 int デフォルト false; 
 name = 'iphone' の store から name,count を選択するための cur カーソルを宣言します。 
 見つからない場合の続行ハンドラーを宣言し、done = true を設定します。 
 合計を 0 に設定します。 
 オープンカー; 
 cur を n,c にフェッチします。 
 (行われていない)しながら行う 
  合計を合計 + c に設定します。 
  cur を n,c にフェッチします。 
 終了しながら; 
  
 クローズカー; 
 合計を選択; 
終わり; 
 
StatisticStore1() を呼び出します。

3 番目の方法は、繰り返し実行を使用することです。

StatisticStore2 が存在する場合は手順を削除します。 
プロシージャ StatisticStore2() を作成します。 
始める 
 c int を宣言します。 
 n varchar(20)を宣言します。 
 合計 int のデフォルトを 0 と宣言します。 
 宣言完了 int デフォルト false; 
 name = 'iphone' の store から name,count を選択するための cur カーソルを宣言します。 
 見つからない場合の続行ハンドラーを宣言し、done = true を設定します。 
 合計を 0 に設定します。 
 オープンカー; 
 繰り返す 
 cur を n,c にフェッチします。 
 完了しない場合は 
  合計を合計 + c に設定します。 
 終了の場合; 
 完了するまで繰り返します。 
 クローズカー; 
 合計を選択; 
終わり; 
 
StatisticStore2() を呼び出します。

ネストされたカーソル

MySQL では、各 begin end ブロックは独立したスコープ領域です。MySQL では同じエラー イベントを 1 回しか定義できないため、複数回定義すると、コンパイル時に同じブロックで宣言された重複ハンドラーが表示されます。

StatisticStore3 が存在する場合は手順を削除します。 
プロシージャ StatisticStore3() を作成します。 
始める 
 _n varchar(20)を宣言します。 
 宣言完了 int デフォルト false; 
 名前でストアグループから名前を選択するための cur カーソルを宣言します。 
 見つからない場合の続行ハンドラーを宣言し、done = true を設定します。 
 オープンカー; 
 read_loop:ループ 
 cur を _n にフェッチします。 
 完了したら 
  read_loop を終了します。 
 終了の場合; 
 始める 
  c int を宣言します。 
  n varchar(20)を宣言します。 
  合計 int のデフォルトを 0 と宣言します。 
  宣言完了 int デフォルト false; 
  name = 'iphone' の store から name,count を選択するための cur カーソルを宣言します。 
  見つからない場合の続行ハンドラーを宣言し、done = true を設定します。 
  合計を 0 に設定します。 
  オープンカー; 
  iphone_loop:ループ 
  cur を n,c にフェッチします。 
  完了したら 
   iphone_loop を終了します。 
  終了の場合; 
  合計を合計 + c に設定します。 
  ループを終了します。 
  クローズカー; 
  _n,n,合計を選択します。 
 終わり; 
 始める 
   c int を宣言します。 
   n varchar(20)を宣言します。 
   合計 int のデフォルトを 0 と宣言します。 
   宣言完了 int デフォルト false; 
   name = 'android' の store から name,count を選択するための cur カーソルを宣言します。 
   見つからない場合の続行ハンドラーを宣言し、done = true を設定します。 
   合計を 0 に設定します。 
   オープンカー; 
   android_loop:ループ 
   cur を n,c にフェッチします。 
   完了したら 
    android_loop を終了します。 
   終了の場合; 
   合計を合計 + c に設定します。 
   ループを終了します。 
   クローズカー; 
  _n,n,合計を選択します。 
 終わり; 
 始める 
  
 終わり; 
 ループを終了します。 
 クローズカー; 
終わり; 
 
StatisticStore3() を呼び出します。

上記はネストされたループを実装するためのものですが、もちろんこの例は無理があります。とりあえず見てみましょう。

動的SQL

MySQLは動的SQL関数をサポートしている

@sqlStr を 'select * from table where condition1 = ?' に設定します。 
@sqlStr 用に s1 を準備します。 
-- 複数のパラメータがある場合は、カンマで区切ります。@condition1 を使用して s1 を実行します。 
-- 手動で解放するか、接続が閉じられると、サーバーは自動的に deallocate prepare s1 をリサイクルします。

以上がMySQLカーソルの詳しい説明です。MySQLカーソルの詳細については、123WORDPRESS.COMの他の関連記事もご覧ください。

以下もご興味があるかもしれません:
  • MySQL カーソルの定義と使用法
  • カーソル ループを使用して、MySQL ストアド プロシージャで一時テーブルを読み取る
  • MySQLでカーソルを宣言する方法
  • MySQL カーソルの原理と使用例の分析
  • Pythonで徹底的にわかるMySQLデータベース操作(カーソル解説)
  • MySQLストアドプロシージャにおけるカーソル(DECLARE)の原理と使い方の詳細な説明
  • MySQL カーソルの概念と使用法の詳細な説明
  • MySQL ストアド プロシージャ、カーソル、トランザクションの例の詳細な説明
  • Mysql ストアド プロシージャでカーソルを使用する例
  • カーソルを使用したMySQLストアドプロシージャネストループのサンプルコード
  • MySQL ストアド プロシージャでカーソル ループを終了して継続する例
  • MySQL カーソル関数と使用法

<<:  Zabbixで指定時間内の変化値を設定する方法の詳細な説明

>>:  Vueはファイルのアップロードとダウンロード機能を実装します

推薦する

一般的な JavaScript メモリ エラーと解決策

目次1. タイマー監視2. イベント監視3.オブザーバー4. ウィンドウオブジェクト5. DOM参照...

Dockerイメージのエクスポートとインポート操作

基本イメージが以前に構成されていて、これらのイメージが他の場所でも必要な場合はどうなりますか?回答:...

Vue ミックスインの使用方法とオプションのマージの詳細な説明

目次1. コンポーネントでの使用2. オプションのマージ要約する1. コンポーネントでの使用Mixi...

MySql5.7.18 の文字セット構成の詳細なグラフィック説明

背景:かなり前(2017.6.5、記事にはタイムリーさがあり、特に使用されているツールは頻繁に更新さ...

垂直方向の中央揃えをエレガントに実現する方法を教えます(推奨)

序文CSS で水平方向と垂直方向に中央揃えする方法はたくさんあります。この記事で紹介する方法は非常に...

5つのクールで実用的なHTMLタグと属性の紹介

実はこれもクリックベイトのタイトルであり、「派手」とは言えません。ただ私が無知で、こうしたラベルを見...

DockerコンテナにNFS共有ディレクトリをマウントする実装

以前、https://www.jb51.net/article/205922.htm で、Docke...

Node.jsをゼロから学ぶ

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

vue3とvue2の利点の比較

目次利点1: diffアルゴリズムの最適化利点2: ホイスト静的静的リフティング利点3: cache...

CentOS6.7 mysql5.6.33 でデータファイルの場所を変更する方法

問題: MySQL がデータ ファイルを保存するパーティションの容量が小さく、現在いっぱいになってい...

Mysqlのインポートとエクスポート時に発生する問題の解決

背景すべての業務を Docker の運用管理に移行してから、一連の落とし穴に遭遇しましたが、今回は ...

CentOS 7 で Python を 3.6.6 にアップグレードした後に発生する yum エラー問題の解決方法の概要

最近、テスト サーバーのオペレーティング システムを Cent0S 7.5 にアップグレードし、Py...

MySQL kill コマンドの使用ガイド

KILL [接続 | クエリ] processlist_id MySQL では、各接続は個別のスレ...

MySQL 8.0.24 バージョンのインストールと設定方法のグラフィックチュートリアル

この記事ではMySQL 8.0.24バージョンのインストールと設定方法を記録し、皆さんと共有しますM...

JavaScript ES6 分割演算子の理解と応用

目次序文脱構築記号の役割使い方分割割り当ての適用アプリケーションの簡単な紹介JSONデータを抽出する...