MySQLでストアド&カーソル使用

MySQL上で大量のデータコンバートをしたいので、以前Microsoft SQL Serverを使っていた時のようにカーソルを使った処理ができないのか調べていました。そしたらば問題なくカーソルが使えるんですね。insertやupdateの一括処理でできれば一番速いのですが、1レコードずつループで処理しなければならない場面では、カーソルが便利です。
ストアドプロシージャとカーソルの使い方は、サイト『MySQLストアドプロシージャ入門』を参考にしたのですが、デリミタ(delimter)の宣言をしないと上手くいかなかったのでその部分の変更と、カーソルのfetchを以前MSSQLServerでやっていた書き方に近いように変更してみました。デリミタについては、書籍『現場で使える MySQL (DB Magazine SELECTION)』の解説で理解しました。
下記が、addressテーブルからidとnameを取り出して1行ずつ表示するストアドプロシージャのサンプルです。

delimiter //
CREATE PROCEDURE sp_looptest()
BEGIN
 -- ハンドラで利用する変数 v_done を宣言
 DECLARE v_done INT DEFAULT 0;
 -- フェッチした値を格納する変数
 DECLARE v_id INT;
 DECLARE v_name VARCHAR(255);
 -- カーソル宣言
 DECLARE v_cur cursor FOR
 SELECT id,name FROM address LIMIT 10;
 -- SQLステートが02000の場合にv_doneを1にするハンドラを宣言
 DECLARE continue handler FOR sqlstate '02000' SET v_done = 1;
 -- カーソルを開く
 OPEN v_cur;
 --最初のカーソルをfetch
 fetch v_cur INTO v_id,v_name;
 -- while関数で繰り返えさせる
 while v_done != 1 do
   -- メイン処理
   SELECT v_id,v_name FROM dual;
   -- 次のカーソルをfetch
   fetch v_cur INTO v_id,v_name;
 END while;
 -- 最後にカーソルを閉じる
 close v_cur;
END;
//
delimiter ;

MSSQLServerと大きく違うのは、continue handlerという変数が使えるということですね。イベントハンドラ的に、この条件の時はこうなる、という記述をすることができます。
これで大量データの処理が進みそうです。

スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク

コメント

  1. […] 先週に引き続き、MySQLでストアドプロシージャを作っていた訳ですが、ながーいinsert〜select文を追加したところ、文法エラーで動かなくなってしまいました。なぜだろうと思ってselect文 […]