【MySQL】カーソルを使ったプロシージャ

スポンサーリンク

前回に引き続き、カーソル(CURSOR)についての記事です。

今回は、カーソルを使ったプロシージャを解説します。

 

カーソルの基本については前回の記事をご覧ください。

あわせてプロシージャの基本もご覧ください。

カーソルを実行してみる

以下プロシージャはカーソルで取得したデータのidが奇数か偶数かを判断し、contentカラムを更新します。

CREATE PROCEDURE curdemo()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE b INT;
  DECLARE cur1 CURSOR FOR SELECT id FROM movies;-- カーソルを定義
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;-- 最終レコードに到達した際の処理
 
  OPEN cur1;-- カーソルオープン(実行)
 
  read_loop: LOOP-- ループ開始(ループ名:read_loop)
    FETCH cur1 INTO b;-- 変数bにカーソルで取得したレコードを1行ずつ格納
  
    IF (MOD(b,2) = 0) THEN
      UPDATE movies SET content = '偶数' WHERE id = b;
    ELSE
      UPDATE movies SET content = '奇数' WHERE id = b;
    END IF;
  
    IF done THEN-- 最終行に到達したら、ループを抜ける
      LEAVE read_loop;
    END IF;
 
  END LOOP;
 
  CLOSE cur1;-- カーソルを閉じる(メモリの開放)
END;
/

カーソルを定義実行内容

ループする理由

カーソルオープン後にループでの中でフェッチをしています。SELECT結果を1行ずつ取得して、処理しています。(ループ処理により1行ずつ取得しています。)

  read_loop: LOOP-- ループ開始(ループ名:read_loop)
  FETCH cur1 INTO b;-- 変数bにカーソルで取得したレコードを1行ずつ格納

 

yasu
yasu

cur1に保持している取得結果の1行を変数bに代入します。

ループを抜けるタイミング

処理の初めに、次のレコードが見つからない場合の処理を書いています。

例外エラー(NOT FOUND)の場合はdoneをTRUEにします。

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;-- 最終レコードに到達した際の処理

この処理があることによって、カーソルの最終行に到達するとループを抜けられます。

    IF done THEN-- 最終行に到達したら、ループを抜ける
      LEAVE read_loop;
    END IF;

 

おまけ

ハマった箇所を書き留めたいだけです。

 

IF文の等価演算子って「=」なんですね。「==」の構文エラーで時間を無駄にしてしまいましたw

IF (MOD(b,2) = 0) THEN

 

言語が変われば仕様も変わる。

教訓ですw

タイトルとURLをコピーしました