ループを使うと、特定の条件が満たされている間や、データセットをイテレートしている間、同じコードブロックを何度も実行できるんだ。これはタスクの自動化や大量データの処理、繰り返し作業にめっちゃ便利!
例えば、グループの子供たち全員に手作業でキャンディーを配るとしたら、カオスだよね!でも、子供たちのリストを順番に回って一人ずつキャンディーを渡せばOK。この「リストを回る」ってのがループなんだ。
PostgreSQLではいくつかのループが使えるよ:
LOOP— 明示的に止めるまでずっと実行される汎用ループ。FOR— 数値の範囲やクエリ結果を指定回数イテレートするループ。WHILE— 条件がtrueの間だけ実行されるループ。
それぞれのループを詳しく見ていこう!
無限ループ:LOOP
LOOPはPL/pgSQLの基本的なループで、コードブロックを繰り返し実行するよ。このループは無限に動き続けるから、EXITコマンドで手動で抜ける必要がある。
構文:
LOOP
-- ここに自分のコードを書く
END LOOP;
例を見てみよう。LOOPで1から10までの合計を計算するよ:
DO $$
DECLARE
counter INT := 1;
sum INT := 0;
BEGIN
LOOP
sum := sum + counter; -- 現在のカウンター値を足す
counter := counter + 1; -- カウンターを増やす
-- カウンターが10を超えたらループ終了
IF counter > 10 THEN
EXIT;
END IF;
END LOOP;
RAISE NOTICE '1から10までの合計: %', sum;
END $$;
counter変数は毎回増える。IF counter > 10 THEN EXIT;の条件でカウンターが10を超えたらループ終了。- 最後に合計を表示するよ。
範囲やデータセットのループ: FOR
2つ目のループ、FORは次の用途で使えるよ:
- 数値の範囲をイテレートする。
- SQLクエリの結果をイテレートする。
数値範囲のループ
構文:
FOR variable IN [REVERSE] start..end LOOP
-- ここに自分のコードを書く
END LOOP;
1から5までの数字を表示してみよう:
DO $$
BEGIN
FOR i IN 1..5 LOOP
RAISE NOTICE '現在の値: %', i;
END LOOP;
END $$;
逆順の例:
DO $$
BEGIN
FOR i IN REVERSE 5..1 LOOP
RAISE NOTICE '逆順: %', i;
END LOOP;
END $$;
SQLクエリ結果のループ
このパターンはテーブルの行を処理したいときに便利!
構文:
FOR variable IN QUERY (SELECT ...) LOOP
-- ここに自分のコードを書く
END LOOP;
テーブルstudentsの行をイテレートする例:
DO $$
DECLARE
student_name TEXT;
BEGIN
FOR student_name IN QUERY (SELECT name FROM students) LOOP
RAISE NOTICE 'やあ、%!', student_name;
END LOOP;
END $$;
条件付きループ:WHILE
WHILEは指定した条件がtrueの間だけ実行されるループだよ。
構文:
WHILE 条件 LOOP
-- ここに自分のコードを書く
END LOOP;
WHILEで1から10までの合計を計算してみよう:
DO $$
DECLARE
counter INT := 1;
sum INT := 0;
BEGIN
WHILE counter <= 10 LOOP
sum := sum + counter;
counter := counter + 1;
END LOOP;
RAISE NOTICE '1から10までの合計: %', sum;
END $$;
リアルな例
ループの基本がわかったところで、実際の使い方を見てみよう!
例1: 掛け算表の生成
DO $$
DECLARE
i INT;
j INT;
BEGIN
FOR i IN 1..5 LOOP
FOR j IN 1..5 LOOP
RAISE NOTICE '% x % = %', i, j, i * j;
END LOOP;
END LOOP;
END $$;
例2: クエリ結果のイテレーション。 例えば、productsテーブルにidとpriceカラムがあるとする。全商品の価格を10%アップデートしよう。
DO $$
DECLARE
prod RECORD;
BEGIN
FOR prod IN QUERY (SELECT id, price FROM products) LOOP
UPDATE products
SET price = prod.price * 1.1
WHERE id = prod.id;
END LOOP;
END $$;
よくあるミスとその回避法
LOOPやWHILEでの無限ループ。 抜ける条件(EXITやWHILEの正しい条件)を忘れると、ループが永遠に終わらない。ブレーキなしで車を運転するようなもんだね。
クエリ結果のイテレーション時のエラー。 期待したデータ構造と違うと、FOR IN QUERYループでエラーになることがあるよ。
ループ内の非効率なクエリ。 例えば、毎回UPDATEを実行するとめっちゃ遅くなる。こういう場合はループじゃなくて1つのSQLクエリでまとめて処理した方がいいよ。
GO TO FULL VERSION