MySQL カーソル関数と使用法

MySQL カーソル関数と使用法

意味

クエリの結果をトラバースし、トラバースされた各データを処理する必要がある状況に遭遇することがよくあります。このような場合にカーソルが使用されます。
つまり、カーソルは、MySQL サーバーに保存されているデータを処理するためのデータベース クエリ メソッドです。結果セット内のデータを表示または処理するために、カーソルは結果セット内のデータを 1 行ずつ走査する機能を提供します。
カーソルは主にループ処理、ストアド プロシージャ、関数、トリガーで使用されます。

カーソルの役割

たとえば、上記の学生の場合、各ユーザーを走査し、他のコメントに基づいてポイントを加算または減算する必要があります。現時点では、すべての学生情報(成績を含む)を照会する必要があります。

学生から学生ID、学生名、スコアを選択します。

実行後、生徒データのセットが返されます。生徒データを 1 つずつ走査し、特定の状況に基づいてポイントを追加する必要がある場合は、カーソルを使用する必要があります。
カーソルは、選択されたデータの最初の行を指すポインターに相当します。ポインターを移動することで、後続のデータを移動できます。

カーソルの使用

  • カーソルを宣言する: カーソルを作成し、カーソルが移動する必要がある選択クエリを指定します。カーソルが宣言されているときは、SQL は実行されません。
  • カーソルを開きます。カーソルが開かれると、カーソルに対応する選択ステートメントが実行されます。
  • データのトラバース: カーソルを使用して、選択結果の各データ行をループし、処理します。
  • ビジネス操作: トラバースされたデータの各行を操作するプロセス。実行する必要がある任意のステートメントを配置できます (追加、削除、変更、チェック): これは特定の状況によって異なります。
  • カーソルを閉じます: 使用後はカーソルを解放する必要があります。

注意: 使用される一時フィールドは、カーソルを定義する前に宣言する必要があります。

カーソルの宣言

DECLARE cursor_name CURSOR FOR select_statement;

カーソルを宣言します。サブルーチン内で複数のカーソルを定義することもできますが、ブロック内の各カーソルには一意の名前を付ける必要があります。カーソルを宣言した後も単一の操作になりますが、SELECT ステートメントには INTO 句を含めることはできません。
begin end で宣言できるカーソルは 1 つだけです。

カーソルを開く

OPEN カーソル名;

以前に宣言されたカーソルを開きます。

カーソルデータのトラバース

FETCH cursor_name INTO var_list;

このステートメントは、指定されたオープン カーソルを使用して次の行 (存在する場合) をフェッチし、カーソル ポインタを進めます。現在の行の結果を取得し、その結果を対応する変数に格納し、カーソル ポインターを次の行のデータにポイントします。
fetch が呼び出されると、現在の行のデータが取得されます。現在の行にデータがない場合、MySQL 内で NOT FOUND エラーが発生します。

カーソルを閉じる

カーソル名を閉じます。

使用後は必ずカーソルを閉じてください。

カーソルの例

生徒の得点と追加ポイントの計算を含む関数を記述する

データ基盤

mysql> 学生から * を選択します。
+-----------+-------------+--------+---------+
| 学生ID | 学生名 | スコア | クラスID |
+-----------+-------------+--------+---------+
| 1 | ブランド | 97.5 | 1 |
| 2 | ヘレン | 96.5 | 1 |
| 3 | リン | 96 | 1 |
| 4 | ソル | 97 | 1 |
| 5 | b1 | 81 | 2 |
| 6 | b2 | 82 | 2 |
| 7 | c1 | 71 | 3 |
| 8 | c2 | 72.5 | 3 |
| 9 | ララ | 73 | 0 |
| 10 | A | 99 | 3 |
| 16 | テスト1 | 100 | 0 |
| 17 | トリガー2 | 107 | 0 |
| 22 | トリガー1 | 100 | 0 |
+-----------+-------------+--------+---------+
13行セット

カーソルを使用する関数の記述

ここの注釈は非常に明確です

マイSQL>
/* 関数が存在する場合は削除します */
fun_test が存在する場合は関数を削除します。
/* 文の終わりは $*/
区切り文字 $
/* 要件を満たす各学生にポイントを追加する関数を作成します。追加されるポイントは、指定された値 max_score を超えることはできません。*/
関数 fun_test(max_score 小数点(10,2)) を作成します。
戻り値 int
始める
/*リアルタイムの StudentId 変数を定義する*/
var_studentId int を DEFAULT 0 として宣言します。
/*計算されたスコアの変数を定義します*/
var_score を10進数(10,2)で宣言します。デフォルトは0です。
/*カーソル終了マーク変数を定義する*/
var_done int を DEFAULT FALSE として宣言します。
/*カーソルを作成する*/
DECLARE cur_test CURSOR FOR SELECT studentid,score from students where classid<>0;
/*カーソルが終了すると、var_done が true に設定されます。var_done を使用して、カーソルが後で終了したかどうかを判断できます。*/
NOT FOUND SET var_done=TRUE の継続ハンドラーを宣言します。
/*カーソルを開く*/
cur_test を開きます。
/*カーソルをループするにはLoopを使用します*/
select_loop:ループ
/*まず現在の行のデータを取得し、次に現在の行のデータをvar_studentId、var_scoreに格納します。データ行がない場合、var_doneはtrueに設定されます*/
cur_test を var_studentId、var_score にフェッチします。
/*var_done を使用してカーソルが終了したかどうかを判断し、ループを終了します*/
var_doneの場合
select_loopを終了します。
終了の場合;
/* var_score 値にランダムな値を追加します。この値は指定されたスコアを超えることはできません。*/
var_score = var_score + LEAST(ROUND(rand()*10,0),max_score); を設定します。
学生を更新します。score = var_score を設定します。ただし、studentId = var_studentId です。
ループを終了;
/*カーソルを閉じる*/
cur_test を閉じます。
/*結果を返す: 実際の状況に応じて必要なコンテンツを返すことができます*/
1 を返します。
終了 $
/*終了文字は;に設定されています*/
区切り文字 ;
クエリは正常です。影響を受けた行は 0 行です

関数の呼び出し

マイSQL>
/* パラメータは 8 で、ボーナスポイントの上限が 8 であることを示します */
fun_test(8)を選択します。
+-------------+
| 楽しいテスト(8) |
+-------------+
| 1 |
+-------------+
セット内の1行

結果を見る

元のスコア値と比較すると、スコアにランダムな値が加算されていることがわかりますが、与えられたスコア8を超えていません。

mysql> 学生から * を選択します。
+-----------+-------------+--------+---------+
| 学生ID | 学生名 | スコア | クラスID |
+-----------+-------------+--------+---------+
| 1 | ブランド | 105.5 | 1 |
| 2 | ヘレン | 98.5 | 1 |
| 3 | リン | 97 | 1 |
| 4 | ソル | 97 | 1 |
| 5 | b1 | 89 | 2 |
| 6 | b2 | 90 | 2 |
| 7 | c1 | 76 | 3 |
| 8 | c2 | 73.5 | 3 |
| 9 | ララ | 73 | 0 |
| 10 | A | 100 | 3 |
| 16 | テスト1 | 100 | 0 |
| 17 | トリガー2 | 107 | 0 |
| 22 | トリガー1 | 100 | 0 |
+-----------+-------------+--------+---------+
13行セット

トリガーログを表示

条件を満たしスコアが変更されたデータは 9 件あり、すべてトリガーによってログに記録されています。

マイSQL>
/*前回の記事では、students テーブルが変更されたときにログをトリガーするトリガーを作成しました*/
トリガーログから * を選択します。
+----+--------------+--------------+-----------------------------------------+
| id | トリガー時間 | トリガーイベント | メモ |
+----+--------------+--------------+-----------------------------------------+
| 1 | 後 | 挿入 | 新しい学生情報、ID:21 |
| 2 | 後 | 更新 | 学生情報を更新、ID:21 |
| 3 | 後 | 更新 | 学生情報を削除、ID:21 |
| 4 | 更新後 | から:test2,101.00 へ:trigger2,106.00 |
| 5 | 更新後 | トリガー 2,106.00 からトリガー 2,107.00 へ |
| 6 | 後 | 更新 | 学生情報を削除、ID:11 |
| 7 | 更新後 | from:brand,97.50 to:brand,105.50 |
| 8 | 更新後 | から:helen,96.50 へ:helen,98.50 |
| 9 | 更新後 | from:lyn,96.00 to:lyn,97.00 |
| 10 | 更新後 | from:sol,97.00 to:sol,97.00 |
| 11 | 更新後 | から:b1,81.00 へ:b1,89.00 |
| 12 | 更新後 | から:b2,82.00 へ:b2,90.00 |
| 13 | 更新後 | から:c1,71.00 へ:c1,76.00 |
| 14 | 更新後 | c2,72.50 から c2,73.50 へ |
| 15 | 更新後 | から:A,99.00 へ:A,100.00 |
+----+--------------+--------------+-----------------------------------------+
15行セット

カーソル実行プロセス

上記の例に従って、このカーソルの実行プロセスを分析します。
1. カーソルを作成し、データ ソースを学生テーブルから取得しました。
2. カーソルにはポインタがあります。カーソルが開かれると、カーソルに対応する選択ステートメントが実行され、このポインタは選択結果のレコードの最初の行を指します。
3. フェッチカーソル名が呼び出されると、現在の行のデータが取得されます。現在の行にデータがない場合、NOT FOUND例外がトリガーされます。
NOT FOUND 例外がトリガーされた場合、上記のように変数を使用してそれをマークできます: DECLARE CONTINUE HANDLER FOR NOT FOUND SET var_done=TRUE;
変数 var_done の値を TRUE に設定します。var_done の値を使用して、ループの終了を制御できます: LEAVE select_loop;。
現在の行にデータがある場合、次のステートメントに示すように、現在の行のデータは対応する変数に格納され、カーソル ポインターは次のデータ行を指します。FETCH cur_test INTO var_studentId,var_score;

要約する

1. カーソルはクエリ結果を移動するために使用されます。
2. カーソルを使用するプロセス: カーソルを宣言し、カーソルを開き、カーソルを移動し、カーソルを閉じます。
3. カーソルは主に、ループ処理、ストアド プロシージャ、および結果セットを照会する関数で使用されます。
4. カーソルの欠点は、行単位でしか操作できないことです。データ量が多く、速度が遅すぎる場合には適用できません。ほとんどのデータベースはコレクション指向であり、ビジネスは比較的複雑です。カーソルを使用するとデッドロックが発生し、他のビジネス操作に影響する可能性があるため、お勧めできません。 データ量が多い場合、カーソルを使用するとメモリ不足が発生する可能性があります。

上記はMySQLカーソルの詳細な分析です。MySQLカーソルの詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQLでカーソルトリガーを使用する方法
  • MySQL カーソルの定義と使用法
  • MySQLでカーソルを宣言する方法
  • MySQLカーソルの詳細な紹介

<<:  CSS3はさまざまな境界効果を実現します

>>:  Vue で v-for を更新する方法

推薦する

Elementのメッセージポップアップウィンドウが繰り返しポップアップする問題の解決

目次1. 使用2. メッセージポップアップウィンドウが繰り返し表示される問題を解決する1. 使用Vu...

html-webpack-plugin の使用方法の詳細な説明

最近、React プロジェクトで初めてhtml-webapck-pluginプラグインを使用しました...

JavaScript で文字列を数値に変換する方法

目次1.parseInt(文字列、基数) 2. 数値() 3.parseFloat()主なメソッドは...

Vueはvueメタ情報を使用して各ページのタイトルとメタ情報を設定します。

title: vue は vue-meta-info を使用して各ページのタイトルとメタ情報を設定...

JavaScript イベントの概念の詳細な説明 (静的登録と動的登録の区別)

目次js のイベントイベントタイプ一般的なイベントイベント登録静的および動的登録の例onload 読...

lastInfdexOf 関数の MySQL 実装例

MySQL では lastIndexOf に似た関数を使用する必要がある場合もありますが、すぐに使用...

MySQLインデックスに関する詳細を共有する

数日前、同僚からMySQLのインデックスについて質問を受けました。大体わかっているのですが、まだ練習...

ページ内の検索エンジンの呼び出しはBaiduを例に挙げています

今日、突然、自分のウェブページで Google や Baidu のような強力な検索エンジンを呼び出す...

Vue が Web オンラインチャット機能を実現

この記事では、Webオンラインチャットを実装するためのVueの具体的なコードを参考までに紹介します。...

React、Angular、Vueの3つの主要なフロントエンド技術の詳細説明

目次1. 反応する基本的な使い方注目すべき機能クラスコンポーネント仮想DOMライフサイクルメソッドJ...

JavaScriptはクリックするとランダムなグラフィックを生成します

この記事では、クリックするとランダムグラフィックの生成を実現するJavaScriptの具体的なコード...

RedHat 6.5 に MySQL 5.7 をインストールするための詳細なチュートリアル

RedHat6.5インストールMySQL5.7チュートリアル共有、参考までに、具体的な内容は次のとお...

ECMAScriptにおけるプリミティブ値と参照値の詳しい説明

目次序文動的プロパティとは何ですか?値のコピー値の種類を決定する要約する序文これは JavaScri...

ドメイン名、ポート、異なるIPに基づくnginx仮想ホスト設定の実装

1. nginx仮想ホストの設定仮想ホストを使用すると、実行する Web サイトごとに個別の Ngi...

Mysqlはフィールドスプライシングのための3つの関数を実装している

データをオペレーションにエクスポートする場合、フィールドの結合は避けられません。MySQL でこれが...