【SQL】SELECTしたデータを1行ずつ読み込む方法について【カーソル】
こんにちは、たけのこです!
システム開発では、データベース操作は必須級の技術ですが、
その中でも今回は、カーソルという機能に絞って解説します。
カーソルはストアドプロシージャの花形とも言われています。
複雑なデータを扱う際にとても便利なので、使い方をマスターしておきましょう!
カーソルとは?
カーソルとは、SELECT文などで抽出した結果を1行ずつ読み取ることのできる機能です。
基本的にストアドプロシージャで利用され、
- 1行ずつ条件分けしてinsertしたい時
- 複雑な条件でupdateしたい時
などに使われます。
カーソルを使用する流れについて
カーソルは他のSQL構文と違い、手順が多いので戸惑ってしまいそうですが、流れに沿って実装していけば案外簡単です。
実際にカーソルを利用したストアドプロシージャのスクリプトを見ながら、使い方を解説します!
ストアドプロシージャでのカーソルの利用
今回、以下3つのテーブルを用意して、MST_Usersにいくつかデータを登録しています。
また、実装していくストアドプロシージャの条件は以下の通りです。
- MST_Usersのageが18以上の場合、adult_Usersに登録
- MST_Usersのageが18未満の場合、kids_Usersに登録
カーソルの宣言
最初にカーソルを宣言します。カーソルはSELECTクエリを用いて、処理したいデータを指定します。
1DECLARE user_cursor CURSOR FOR
2SELECT
3 user_id,
4 name,
5 age,
6 remarks
7FROM
8 MST_Users;
継続ハンドラの設定
カーソルがすべての行を読み終えたときに、自動的に処理を終了するように継続ハンドラを設定します。
1DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
「DECLARE」句でCONTINUE HANDLERハンドラを定義。
「NOT FOUND SET finished = 1;」でデータが見つからなくなったら、ループが終わるように設定しています!
カーソルの開始とデータの読み取り
1OPEN user_cursor;
2read_loop: LOOP
3 FETCH user_cursor INTO u_id, u_name, u_age, u_remarks;
4 IF finished = 1 THEN
5 LEAVE read_loop;
6 END IF;
7
8 IF u_age >= 18 THEN
9 INSERT INTO adult_Users (user_id, name, age, remarks) VALUES (u_id, u_name, u_age, u_remarks);
10 ELSE
11 INSERT INTO kids_Users (user_id, name, age, remarks) VALUES (u_id, u_name, u_age, u_remarks);
12 END IF;
13END LOOP;
14CLOSE user_cursor;
OPEN句で宣言したカーソルをオープンし、利用できる状態にします。
次に、「read_loop: LOOP」でループを開始し、「FETCH user_cursor INTO u_id, u_name, u_age, u_remarks;」で1行ずつ読み取ったデータを
- u_id
- u_name
- u_age
- u_remarks
の変数の中にそれぞれ代入します。
代入したら、後はIF文で条件分けして各テーブルにデータ登録を行なっています。
最後に、「CLOSE user_cursor;」でカーソルを閉じて終わりです!
ここまで解説したカーソルを利用したストアドプロシージャの全コードは以下の通りです。
1DELIMITER $$
2
3CREATE PROCEDURE InsertUsers()
4BEGIN
5 DECLARE finished INTEGER DEFAULT 0;
6 DECLARE u_id INT;
7 DECLARE u_name VARCHAR(100);
8 DECLARE u_age INT;
9 DECLARE u_remarks TEXT;
10 DECLARE user_cursor CURSOR FOR SELECT user_id, name, age, remarks FROM MST_Users;
11 DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
12
13 OPEN user_cursor;
14
15 read_loop: LOOP
16 FETCH user_cursor INTO u_id, u_name, u_age, u_remarks;
17 IF finished = 1 THEN
18 LEAVE read_loop;
19 END IF;
20
21 IF u_age >= 18 THEN
22 INSERT INTO adult_Users (user_id, name, age, remarks) VALUES (u_id, u_name, u_age, u_remarks);
23 ELSE
24 INSERT INTO kids_Users (user_id, name, age, remarks) VALUES (u_id, u_name, u_age, u_remarks);
25 END IF;
26 END LOOP;
27
28 CLOSE user_cursor;
29END$$
30
31DELIMITER ;
32
まとめ
ということで、今回はSQLのカーソル機能について紹介しました。
コードは長いですが、使いこなせるようになればデータ操作の幅が大きく広がります。
これからデータ操作のプロジェクトに参画する予定の人や、データ操作をすることの多い人はぜひ覚えていってください。
というわけで、今回はこの辺りで!
ありがとうございました!