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 を更新する方法

推薦する

TCPソケットSYNキューとAcceptキューの差異分析

まず、「LISTENING」状態の TCP ソケットには 2 つの独立したキューがあることを理解する...

MySQLストレージ時間タイプの選択に関する問題の説明

MySQL では、datetime 型は通常、時間を保存するために使用されますが、現在では多くのシス...

優れた登録プロセスの手順

ウェブサイトにとって、これは最も基本的な機能です。それでは、登録プロセスに含まれる手順を見てみましょ...

Vue+Vantはトップ検索バーを実装します

この記事では、参考までに、Vue+Vant のトップ検索バーを実装するための具体的なコードを紹介しま...

Docker イメージ管理の一般的な操作コード例

ミラーリングも Docker のコアコンポーネントの 1 つです。ミラーリングはコンテナ操作の基盤で...

Centos7 システムでの python2 と python3 の共存

最初のステップは、Python のバージョン番号とインストール パスを確認することです。 上記のビュ...

フロントエンド HTML+CSS+JS を使用してシンプルな TODOLIST 関数を開発する (メモ帳)

目次1. 簡単な紹介2. スクリーンショットを実行する3. コードの紹介4. まとめ1. 簡単な紹介...

Tomcat の設定と Eclipse での起動方法

目次Tomcat8のインストールと設定方法tomcat ダウンロードTomcat マネージャーを有効...

WeChatアプレットは記録機能を実装します

この記事では、WeChatアプレットのレコード機能を実装するための具体的なコードを参考までに紹介しま...

Linux での UDP について学ぶ

目次1. UDPとLinuxの基礎の紹介2. 各機能の使い方1. ソケット機能の使用2. バインド機...

Web インタビュー: MVC と MVVM の違いと、Vue が MVVM に完全に準拠していない理由

目次MVCとMVVMの違い前述のMVCC の概要長所と短所MVVM概要MVVM 実装者 — Vue ...

CSSの使用に関する深い理解 clear:both

clear:both清除浮動これは私が常に持っていた印象ですが、私はこれをめったに使用せず、私の理...

CSS+SVGでBステーションの課金効果を実現するサンプルコード

困難SVG グラフィックの 2 つのマスクの作成まず、コード左側のピンク色のボックスの内容ですこれに...

SQL の左結合と右結合の原理と例の分析

テーブルが 2 つあり、テーブル A のレコードがテーブル B に存在しない可能性があります。左結合...

Dockerを使用してRedisクラスターを構築する方法

目次1. Redis Dockerベースイメージを作成する2. Redisノードイメージを作成する3...