カーソルの実行プロセス全体には、カーソルの宣言(DECLARE)、カーソルの開放(OPEN)、次の行の取得(FETCH)、およびカーソルの閉鎖(CLOSE)が含まれます。
カーソルの宣言(DECLARE)
カーソルを宣言する構文は以下のとおりです:
DECLARE cursor_name CURSOR FOR select_statement
この構文は、カーソルを SELECT ステートメントに関連付けます(SELECT ステートメントには INTO 句を含めることはできません)。SELECT ステートメントは、カーソルがイテレーションする行を取得します。後で行を抽出する場合は、FETCH ステートメントを使用してください。この場合、SELECT ステートメントで取得される列数は、FETCH ステートメントで指定された出力変数の数と一致していなければなりません。
カーソルの宣言は、ハンドラーの宣言より前、変数や条件の宣言より後に記述する必要があります。ストアドプログラムには複数のカーソル宣言を含めることができますが、指定されたブロック内で宣言されるカーソルは一意の名前を持たなければなりません。
ほとんどの場合、INFORMATION_SCHEMA テーブルを使用したカーソルを使用することで、SHOW ステートメントと同等の情報を取得できます。
カーソルの開放(OPEN)
宣言済みのカーソルを開く構文は以下のとおりです:
OPEN cursor_name
次の行の取得(FETCH)
指定されたカーソル(開いている必要があります)に関連付けられた SELECT ステートメントの次の行を取得し、カーソルポインタを進める構文は以下のとおりです:
FETCH [[NEXT] FROM] cursor_name INTO var_name [, var_name] ...
行が存在する場合、取得した列は命名された変数 var_name に格納されます。SELECT ステートメントで取得される列数は、FETCH ステートメントで指定された出力変数の数と一致していなければなりません。
利用可能な行がない場合、データなし状態が発生し、SQLSTATE 値は「02000」となります。この状況を検出するには、例外ハンドラーを設定するか(または NOT FOUND 条件を設定する)必要があります。ただし、SELECT または他の FETCH ステートメントでも同じ状況が発生し、ハンドラーが実行される可能性があることに注意してください。どの操作によってこの状況が引き起こされたかを区別する必要がある場合は、その操作を独自の BEGIN END ブロック内に配置して、自身のハンドラーにのみ関連付けるようにしてください。
カーソルの閉鎖(CLOSE)
以前に開いたカーソルを閉じる構文は以下のとおりです:
CLOSE cursor_name
カーソルが開いていない状態でこのステートメントを実行すると、エラーが発生します。明示的に閉じない限り、カーソルは宣言された BEGIN END ブロックの実行終了時に自動的に閉じられます。
例
obclient> DELIMITER //
obclient> CREATE PROCEDURE hr_curdemo()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE x, y, z INT;
DECLARE cur1 CURSOR FOR SELECT id,salary FROM hr.emp;
DECLARE cur2 CURSOR FOR SELECT avg_sal FROM hr.avg;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
OPEN cur2;
read_loop: LOOP
FETCH cur1 INTO x, y;
FETCH cur2 INTO z;
IF done THEN
LEAVE read_loop;
END IF;
IF y < z THEN
INSERT INTO hr.low_sal VALUES (x,y);
ELSE
INSERT INTO hr.high_sal VALUES (x,z);
END IF;
END LOOP;
CLOSE cur1;
CLOSE cur2;
END //
Query OK, 0 rows affected