シンボルは、オプションの別のいずれかを示し|タグは、[]オプションは、含ま示しています。
需要の背景
我々は、セレクトトラバースプロセスの結果を照会する必要がある場合、どのようにそれを達成するには?
この時点で、我々は結果によりカーソルSELECTクエリを設定し、処理のためにデータの行ごとを横切るカーソルを使用する必要があります。
この部分で
-
カーソルの定義
-
イテレータ
-
カーソルのステップを使用します
-
詳細カーソルの実行
-
シングルカーソルのサンプル
-
ネストされたカーソルのサンプル
データを準備します
ライブラリーを作成します。javacode2018
あなたは、テーブルを作成します。TEST1、TEST2、TEST3を
/*建库javacode2018*/
drop database if exists javacode2018;
create database javacode2018;
/*切换到javacode2018库*/
use javacode2018;
DROP TABLE IF EXISTS test1;
CREATE TABLE test1(a int,b int);
INSERT INTO test1 VALUES (1,2),(3,4),(5,6);
DROP TABLE IF EXISTS test2;
CREATE TABLE test2(a int);
INSERT INTO test2 VALUES (100),(200),(300);
DROP TABLE IF EXISTS test3;
CREATE TABLE test3(b int);
INSERT INTO test3 VALUES (400),(500),(600);
まず、カーソルの定義
カーソル(カーソル)は、データを処理するための方法、またはデータを表示するために設定された処理結果である結果のデータ線を介してカーソルを濃縮する能力を提供します。
カーソルは、ストアド・プロシージャおよび関数に使用することができます。
効果第二に、カーソル
SQLとして:
select a,b from test1;
私たちは、これらのデータの処理を通過したい場合は、上記のクエリは、この時点で我々が動作するようにカーソルを使用することができ、TEST1にデータを返します。
選択データの最初の行を指し示すカーソルポインタに対応し、以下のデータは、ポインタを移動させることにより横断されてもよいです。
第三に、カーソルを使用するステップ
カーソルを宣言するカーソル選択クエリを横断する必要性を指定する必要があり、このプロセスは専用カーソルを作成し、カーソルが宣言されたときに、このSQLを実行しません:。
カーソルを開く:カーソルが対応するselect文を実行します開いているカーソルを。
データを介して:選択カーソルを用いた結果は、各データ線を介してループし、次いで処理しました。
カーソルをクローズします:あなたは閉じなければならないカーソルの使用を終了した後。
第四に、カーソルの構文
カーソルを宣言
DECLARE 游标名称 CURSOR FOR 查询语句;
Aあなただけのカーソルを宣言することができ、エンドを開始します。
カーソルを開きます
open 游标名称;
カーソルを移動します
fetch 游标名称 into 变量列表;
変数結果に対応する、現在の行の結果を削除し、次のラインのデータにカーソルポインタ。
フェッチ、あなたは現在の行のデータ、データがない場合は、現在の行を取得します呼び出す場合、内部のMySQLにつながる
NOT FOUND
エラー。
カーソルをクローズします
close 游标名称;
カーソルの後、使用後に閉じなければなりません。
第五に、単一カーソルのサンプル
TEST1テーブルA、B、およびすべてのフィールドを計算する関数を書きます。
関数を作成します:
/ *関数* /削除
存在する場合にはDROP FUNCTIONをFUN1;
$ /のための/ * *文の終了
デリミタ$は
/ *関数を作成します* /
CREATE FUNCTIONの FUN1 (v_max_aの INT)
RETURNSは int型
BEGIN
/ *結果を格納するために使用される* /
DECLAREのv_totalの int型0 DEFAULT;
/ *現在の行*の値を保持する変数を作成/
DECLAREのV_A DEFAULT INT 0;
/ * / b *表の現在の行を保存するために使用される変数を作成
V_B DECLARE DEFAULT値int 0;
/ *カーソル終了フラグ変数を作成する* /
DECLAREのv_done DEFAULTのFALSE INT;
/ *カーソルを作成する* /
FORがWHERE <= v_max_a TEST1からSELECT A、Bをcur_test1 DECLAREカーソル。
/ *最後のv_doneにカーソルが真で設定し、カーソルが終わり* / v_doneできるかどうかを判断するために
、NOT FOUNDを= TRUE v_doneのハンドラにSETを継続DECLAREを
* / / *設定された初期値v_total
SETのv_total = 0;
/ *オープン・カーソル* /
OPEN cur_test1;
/ *ループ*を使用してカーソルをループ/
:ループ
/ *現在の行のデータを取得し、現在の行がデータでない場合V_A、V_Bが、v_doneに設定するに現在のラインデータ真*に/
へV_A cur_test1 V_bををFETCH;
v_doneカーソルがループを終了し、超えているか否かを判断することにより、/ * * /
v_doneはTHEN IF
LEAVE;
END IFを;
/ * v_total累積値処理の* /
SET v_total = v_total + V_A + V_B;
END LOOP;
/ *カーソルを閉じます* /
CLOSE cur_test1;
/ *戻り結果* /
リターンv_total、
エンド$
/ *設定ターミネータ; * /
DELIMITER;
上記のステートメントは、プロセス内で実行され、次の解決、問題がある可能性があります。
エラーメッセージ:MySQLの関数を作成するには、この関数は、DETERMINISTIC、NOのどれも持っていません表示される SQL、またはSQLデータを読み出し
この関数は、DETERMINISTIC、NO SQLのいずれを有していない、またはその宣言とバイナリSQLデータを読み出します
デフォルト設定では、関数のmysqlを作成することはできません
解決策1:
実行:
GLOBAL log_bin_trust_function_creators = 1を設定します。
しかし、失敗の再起動について
注意:主のスレーブからコピーするときに、それ以外の場合は、マスター・スレーブの同期の失敗につながる設定する必要があります
解決策2:
my.cnfの中で設定し、どの
ログ・ビン・信託機能-クリエイター= 1を
しかし、この必要性は、サービスを再起動します
第六に、カーソルプロセスの詳細
一例として、上記のサンプルコードでは、のは、カーソルの詳細な実行を見てみましょう。
開いたときにカーソルが、ときに、カーソルのポインタがあるカーソルSELECT文に対応する実行され、選択ポインタは、最初の行のレコードの結果を指します。
呼び出されたときにfetch 游标名称
データがトリガされません場合、データは、現在の行を現在の行を取得しますNOT FOUND
例外を。
トリガーときNOT FOUND
とき異常が、我々はそれをマークするために変数を使用することができ、次のコード:
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done=TRUE;
場合、カーソルはデータがトリガされないNOT FOUND
異常が、変数v_down
の値が設定されTURE
、ループができを通じて、v_down
制御サイクルの終了値。
:現在のラインデータ、現在の行が対応する変数に格納されたデータ、およびデータの次の行にカーソルポインタ、次のif文
fetch 游标名称 into 变量列表;
七、ネストされたカーソル
メモリ書き込み手順は、TEST2、TEST3を横断する、フィールドおよびTEST2 TEST3のフィールドbの任意の組み合わせは、TEST1テーブルに挿入されます。
ストアドプロシージャを作成します。
/*删除存储过程*/
DROP PROCEDURE IF EXISTS proc1;
/*声明结束符为$*/
DELIMITER $
/*创建存储过程*/
CREATE PROCEDURE proc1()
BEGIN
/*创建一个变量,用来保存当前行中a的值*/
DECLARE v_a int DEFAULT 0;
/*创建游标结束标志变量*/
DECLARE v_done1 int DEFAULT FALSE;
/*创建游标*/
DECLARE cur_test1 CURSOR FOR SELECT a FROM test2;
/*设置游标结束时v_done1的值为true,可以v_done1来判断游标cur_test1是否结束了*/
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done1=TRUE;
/*打开游标*/
OPEN cur_test1;
/*使用Loop循环遍历游标*/
a:LOOP
FETCH cur_test1 INTO v_a;
/*通过v_done1来判断游标是否结束了,退出循环*/
if v_done1 THEN
LEAVE a;
END IF;
BEGIN
/*创建一个变量,用来保存当前行中b的值*/
DECLARE v_b int DEFAULT 0;
/*创建游标结束标志变量*/
DECLARE v_done2 int DEFAULT FALSE;
/*创建游标*/
DECLARE cur_test2 CURSOR FOR SELECT b FROM test3;
/*设置游标结束时v_done1的值为true,可以v_done1来判断游标cur_test2是否结束了*/
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done2=TRUE;
/*打开游标*/
OPEN cur_test2;
/*使用Loop循环遍历游标*/
b:LOOP
FETCH cur_test2 INTO v_b;
/*通过v_done1来判断游标是否结束了,退出循环*/
if v_done2 THEN
LEAVE b;
END IF;
/*将v_a、v_b插入test1表中*/
INSERT INTO test1 VALUES (v_a,v_b);
END LOOP b;
/*关闭cur_test2游标*/
CLOSE cur_test2;
END;
END LOOP;
/*关闭游标cur_test1*/
CLOSE cur_test1;
END $
/*结束符置为;*/
DELIMITER ;
X.の概要
-
カーソルが横断するクエリ結果を処理するために使用されます
-
カーソルを使用するプロセス:カーソルがクローズされ、カーソルを移動、カーソルを開き、カーソルを宣言する
-
カーソルは、ストアド・プロシージャおよび関数のみを使用することができます
-
A彼女は唯一のカーソルを宣言することができ、エンドを開始
-
単一のネストされたカーソルとカーソルの使用をマスター